// Copyright (c) 2012-2023 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;
}
///
/// 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;
}
///
/// 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(static_cast(obj.Count() * 3.0f));
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);
}
};