// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "../Collections/Array.h"
#include "../Collections/Dictionary.h"
#include "../Delegate.h"
class ArrayExtensions;
///
/// Represents a collection of objects that have a common key.
///
template
class IGrouping : public Array
{
friend ArrayExtensions;
protected:
TKey _key;
public:
///
/// Gets the common key.
///
FORCE_INLINE const TKey& GetKey() const
{
return _key;
}
///
/// Gets the common key.
///
FORCE_INLINE TKey GetKey()
{
return _key;
}
};
///
/// Array collection extension methods and helpers.
///
class ArrayExtensions
{
public:
///
/// Searches for the specified object using a custom query and returns the zero-based index of the first occurrence within the entire collection.
///
/// The target collection.
/// The prediction function. Should return true for the target element to find.
/// The index of the element or -1 if nothing found.
template
static int32 IndexOf(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (predicate(obj[i]))
return i;
}
return INVALID_INDEX;
}
///
/// Searches for the specified object using a custom query and returns it or default value.
///
/// The target collection.
/// The prediction function. Should return true for the target element to find.
/// The first found item or default value if nothing found.
template
static T First(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (predicate(obj[i]))
return obj[i];
}
return T();
}
///
/// Searches for the specified object using a custom query and returns it or default value.
///
/// The target collection.
/// The prediction function. Should return true for the target element to find.
/// The first found item or default value if nothing found.
template
static T* First(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (predicate(obj[i]))
return obj[i];
}
return nullptr;
}
///
/// The Any operator checks, if there are any elements in the collection matching the predicate. It does not select the element, but returns true if at least one element is matched.
///
/// The target collection.
/// The prediction function.
/// True if any element in the collection matches the prediction, otherwise false.
template
static bool Any(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (predicate(obj[i]))
return true;
}
return false;
}
///
/// All Any operator returns true if all elements match the predicate. It does not select the element, but returns true if all elements are matching.
///
/// The target collection.
/// The prediction function.
/// True if all elements in the collection matches the prediction, otherwise false.
template
static int32 All(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (!predicate(obj[i]))
return false;
}
return true;
}
///
/// All Any operator returns true if all elements match the predicate. It does not select the element, but returns true if all elements are matching.
///
/// The target collection.
/// The prediction function.
/// True if all elements in the collection matches the prediction, otherwise false.
template
static int32 All(const Array& obj, const Function& predicate)
{
for (int32 i = 0; i < obj.Count(); i++)
{
if (!predicate(obj[i]))
return false;
}
return true;
}
///
/// Filters a sequence of values based on a predicate.
///
/// The target collection.
/// The prediction function. Return true for elements that should be included in result list.
/// The result list with items that passed the predicate.
template
static void Where(const Array& obj, const Function& predicate, Array& result)
{
for (const T& i : obj)
{
if (predicate(i))
result.Add(i);
}
}
///
/// Filters a sequence of values based on a predicate.
///
/// The target collection.
/// The prediction function. Return true for elements that should be included in result list.
/// The result list with items that passed the predicate.
template
static Array Where(const Array& obj, const Function& predicate)
{
Array result;
Where(obj, predicate, result);
return result;
}
///
/// Projects each element of a sequence into a new form.
///
/// The target collection.
/// A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
/// The result list whose elements are the result of invoking the transform function on each element of source.
template
static void Select(const Array& obj, const Function& selector, Array& result)
{
for (const TSource& i : obj)
result.Add(MoveTemp(selector(i)));
}
///
/// Projects each element of a sequence into a new form.
///
/// The target collection.
/// A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
/// The result list whose elements are the result of invoking the transform function on each element of source.
template
static Array Select(const Array& obj, const Function& selector)
{
Array result;
Select(obj, selector, result);
return result;
}
///
/// Removes all the elements that match the conditions defined by the specified predicate.
///
/// The target collection to modify.
/// A transform function that defines the conditions of the elements to remove.
template
static void RemoveAll(Array& obj, const Function& predicate)
{
for (int32 i = obj.Count() - 1; i >= 0; i--)
{
if (predicate(obj[i]))
obj.RemoveAtKeepOrder(i);
}
}
///
/// Removes all the elements that match the conditions defined by the specified predicate.
///
/// The target collection to process.
/// A transform function that defines the conditions of the elements to remove.
/// The result list whose elements are the result of invoking the transform function on each element of source.
template
static Array RemoveAll(const Array& obj, const Function& predicate)
{
Array result;
for (const T& i : obj)
{
if (!predicate(i))
result.Ass(i);
}
return result;
}
///
/// Groups the elements of a sequence according to a specified key selector function.
///
/// The collection whose elements to group.
/// A function to extract the key for each element.
/// The result collection with groups.
template
static void GroupBy(const Array& obj, const Function& keySelector, Array, AllocationType>& result)
{
Dictionary> data;
for (int32 i = 0; i < obj.Count(); i++)
{
const TKey key = keySelector(obj[i]);
auto& group = data[key];
group._key = key;
group.Add(obj[i]);
}
result.Clear();
data.GetValues(result);
}
};