coveo::linq
Implementation of .NET-like LINQ operators in C++
Functions
group_by / group_values_by / group_by_and_fold / group_values_by_and_fold

Groups elements in a sequence according to their keys. More...

Functions

template<typename KeySelector >
auto coveo::linq::group_by (KeySelector &&key_sel) -> detail::group_by_impl< KeySelector, detail::identity<>, detail::pair_of<>, detail::less<>>
 Groups elements in sequence according to their keys. More...
 
template<typename KeySelector , typename Pred >
auto coveo::linq::group_by (KeySelector &&key_sel, Pred &&pred) -> detail::group_by_impl< KeySelector, detail::identity<>, detail::pair_of<>, Pred >
 Groups elements in sequence according to their keys using predicate. More...
 
template<typename KeySelector , typename ValueSelector >
auto coveo::linq::group_values_by (KeySelector &&key_sel, ValueSelector &&value_sel) -> detail::group_by_impl< KeySelector, ValueSelector, detail::pair_of<>, detail::less<>>
 Groups values in sequence according to their keys. More...
 
template<typename KeySelector , typename ValueSelector , typename Pred >
auto coveo::linq::group_values_by (KeySelector &&key_sel, ValueSelector &&value_sel, Pred &&pred) -> detail::group_by_impl< KeySelector, ValueSelector, detail::pair_of<>, Pred >
 Groups values in sequence according to their keys using predicate. More...
 
template<typename KeySelector , typename ResultSelector >
auto coveo::linq::group_by_and_fold (KeySelector &&key_sel, ResultSelector &&result_sel) -> detail::group_by_impl< KeySelector, detail::identity<>, ResultSelector, detail::less<>>
 Groups elements in sequence according to their keys then folds the results. More...
 
template<typename KeySelector , typename ResultSelector , typename Pred >
auto coveo::linq::group_by_and_fold (KeySelector &&key_sel, ResultSelector &&result_sel, Pred &&pred) -> detail::group_by_impl< KeySelector, detail::identity<>, ResultSelector, Pred >
 Groups elements in sequence according to their keys using predicate, then folds the results. More...
 
template<typename KeySelector , typename ValueSelector , typename ResultSelector >
auto coveo::linq::group_values_by_and_fold (KeySelector &&key_sel, ValueSelector &&value_sel, ResultSelector &&result_sel) -> detail::group_by_impl< KeySelector, ValueSelector, ResultSelector, detail::less<>>
 Groups values in sequence according to their keys then folds the results. More...
 
template<typename KeySelector , typename ValueSelector , typename ResultSelector , typename Pred >
auto coveo::linq::group_values_by_and_fold (KeySelector &&key_sel, ValueSelector &&value_sel, ResultSelector &&result_sel, Pred &&pred) -> detail::group_by_impl< KeySelector, ValueSelector, ResultSelector, Pred >
 Groups values in sequence according to their keys using predicate, then folds the results. More...
 

Detailed Description

The group_by operator (and its siblings) group elements in a sequence according to their keys. Keys are extracted from elements using a key selector. Variants of the operator can also extract values from elements using a value selector, or modify the resulting sequence using a result selector.

.NET equivalent: GroupBy

Function Documentation

◆ group_by() [1/2]

template<typename KeySelector >
auto coveo::linq::group_by ( KeySelector &&  key_sel) -> detail::group_by_impl<KeySelector, detail::identity<>, detail::pair_of<>, detail::less<>>

Scans the input sequence and, for each element, fetches a key using the provided key selector. Then, creates groups of elements that have a common key. The result is a sequence of pairs whose first element is a key and whose second element is a sequence of elements matching that key. The groups are returned in ascending order of key, as determined by operator<().

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto groups = from(DATA)
| group_by([](std::pair<int, std::string> p) { return p.first; });
auto it = std::begin(groups);
auto group1 = *it++;
auto group2 = *it++;
auto group3 = *it++;
// group1.first == 23, group1.second == { { 23, "Hangar" }, { 23, "Jeep" } }
// group2.first == 42, group2.second == { { 42, "Life" }, { 42, "Universe" } }
// group3.first == 66, group3.second == { { 66, "Route" } }
// it == std::end(groups)
Parameters
key_selKey selector, used to extract a key for a sequence element.
Returns
(Once applied) Sequence of pairs whose first element is a key and whose second element is a sequence of matching elements.

◆ group_by() [2/2]

template<typename KeySelector , typename Pred >
auto coveo::linq::group_by ( KeySelector &&  key_sel,
Pred &&  pred 
) -> detail::group_by_impl<KeySelector, detail::identity<>, detail::pair_of<>, Pred>

Scans the input sequence and, for each element, fetches a key using the provided key selector. Then, creates groups of elements that have a common key. The result is a sequence of pairs whose first element is a key and whose second element is a sequence of elements matching that key. The groups are returned in order of key, as determined by the provided predicate. The predicate must provide a strict ordering of the keys, like std::less.

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto groups = from(DATA)
| group_by([](std::pair<int, std::string> p) { return p.first; },
[](int i, int j) { return i > j; });
auto it = std::begin(groups);
auto group1 = *it++;
auto group2 = *it++;
auto group3 = *it++;
// group1.first == 66, group1.second == { { 66, "Route" } }
// group2.first == 42, group2.second == { { 42, "Life" }, { 42, "Universe" } }
// group3.first == 23, group3.second == { { 23, "Hangar" }, { 23, "Jeep" } }
// it == std::end(groups)
Parameters
key_selKey selector, used to extract a key for a sequence element.
predPredicate used to compare the keys.
Returns
(Once applied) Sequence of pairs whose first element is a key and whose second element is a sequence of matching elements.

◆ group_values_by() [1/2]

template<typename KeySelector , typename ValueSelector >
auto coveo::linq::group_values_by ( KeySelector &&  key_sel,
ValueSelector &&  value_sel 
) -> detail::group_by_impl<KeySelector, ValueSelector, detail::pair_of<>, detail::less<>>

Scans the input sequence and, for each element, fetches a key using the provided key selector and a value using the provided value selector. Then, creates groups of values that have a common key. The result is a sequence of pairs whose first element is a key and whose second element is a sequence of values matching that key. The groups are returned in ascending order of key, as determined by operator<().

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto groups = from(DATA)
| group_values_by([](std::pair<int, std::string> p) { return p.first; },
[](std::pair<int, std::string> p) { return p.second; });
auto it = std::begin(groups);
auto group1 = *it++;
auto group2 = *it++;
auto group3 = *it++;
// group1.first == 23, group1.second == { "Hangar", "Jeep" }
// group2.first == 42, group2.second == { "Life", "Universe" }
// group3.first == 66, group3.second == { "Route" }
// it == std::end(groups)
Parameters
key_selKey selector, used to extract a key for a sequence element.
value_selValue selector, used to extract a value for a sequence element.
Returns
(Once applied) Sequence of pairs whose first element is a key and whose second element is a sequence of matching values.

◆ group_values_by() [2/2]

template<typename KeySelector , typename ValueSelector , typename Pred >
auto coveo::linq::group_values_by ( KeySelector &&  key_sel,
ValueSelector &&  value_sel,
Pred &&  pred 
) -> detail::group_by_impl<KeySelector, ValueSelector, detail::pair_of<>, Pred>

Scans the input sequence and, for each element, fetches a key using the provided key selector and a value using the provided value selector. Then, creates groups of values that have a common key. The result is a sequence of pairs whose first element is a key and whose second element is a sequence of values matching that key. The groups are returned in order of key, as determined by the provided predicate. The predicate must provide a strict ordering of the keys, like std::less.

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto groups = from(DATA)
| group_values_by([](std::pair<int, std::string> p) { return p.first; },
[](std::pair<int, std::string> p) { return p.second; },
[](int i, int j) { return i > j; });
auto it = std::begin(groups);
auto group1 = *it++;
auto group2 = *it++;
auto group3 = *it++;
// group1.first == 66, group1.second == { "Route" }
// group2.first == 42, group2.second == { "Life", "Universe" }
// group3.first == 23, group3.second == { "Hangar", "Jeep" }
// it == std::end(groups)
Parameters
key_selKey selector, used to extract a key for a sequence element.
value_selValue selector, used to extract a value for a sequence element.
predPredicate used to compare the keys.
Returns
(Once applied) Sequence of pairs whose first element is a key and whose second element is a sequence of matching values.

◆ group_by_and_fold() [1/2]

template<typename KeySelector , typename ResultSelector >
auto coveo::linq::group_by_and_fold ( KeySelector &&  key_sel,
ResultSelector &&  result_sel 
) -> detail::group_by_impl<KeySelector, detail::identity<>, ResultSelector, detail::less<>>

Scans the input sequence and, for each element, fetches a key using the provided key selector. Then, creates groups of elements that have a common key and uses the provided result selector to convert the groups. The result selector is called with two arguments: a key, and a sequence of elements matching that key. The final result is a sequence of the values returned by the result selector. The result selector is called in ascending order of key, as determined by operator<().

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto res = from(DATA)
| group_by_and_fold([](std::pair<int, std::string> p) { return p.first; },
[](int k, coveo::enumerable<const std::pair<int, std::string>> e) { k + return e.size(); });
// res == { 25, 44, 67 }
Parameters
key_selKey selector, used to extract a key for a sequence element.
result_selResult selector, used to fold groups into final results.
Returns
(Once applied) Sequence of values returned by result_sel.

◆ group_by_and_fold() [2/2]

template<typename KeySelector , typename ResultSelector , typename Pred >
auto coveo::linq::group_by_and_fold ( KeySelector &&  key_sel,
ResultSelector &&  result_sel,
Pred &&  pred 
) -> detail::group_by_impl<KeySelector, detail::identity<>, ResultSelector, Pred>

Scans the input sequence and, for each element, fetches a key using the provided key selector. Then, creates groups of elements that have a common key and uses the provided result selector to convert the groups. The result selector is called with two arguments: a key, and a sequence of elements matching that key. The final result is a sequence of the values returned by the result selector. The result selector is called in order of key, as determined by the provided predicate. The predicate must provide a strict ordering of the keys, like std::less.

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto res = from(DATA)
| group_by_and_fold([](std::pair<int, std::string> p) { return p.first; },
[](int k, coveo::enumerable<const std::pair<int, std::string>> e) { k + return e.size(); },
[](int i, int j) { return i > j; });
// res == { 67, 44, 25 }
Parameters
key_selKey selector, used to extract a key for a sequence element.
result_selResult selector, used to fold groups into final results.
predPredicate used to compare the keys.
Returns
(Once applied) Sequence of values returned by result_sel.

◆ group_values_by_and_fold() [1/2]

template<typename KeySelector , typename ValueSelector , typename ResultSelector >
auto coveo::linq::group_values_by_and_fold ( KeySelector &&  key_sel,
ValueSelector &&  value_sel,
ResultSelector &&  result_sel 
) -> detail::group_by_impl<KeySelector, ValueSelector, ResultSelector, detail::less<>>

Scans the input sequence and, for each element, fetches a key using the provided key selector and a value using the provided value selector. Then, creates groups of values that have a common key and uses the provided result selector to convert the groups. The result selector is called with two arguments: a key, and a sequence of values matching that key. The final result is a sequence of the values returned by the result selector. The result selector is called in ascending order of key, as determined by operator<().

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto res = from(DATA)
| group_values_by_and_fold([](std::pair<int, std::string> p) { return p.first; },
[](std::pair<int, std::string> p) { return p.second; },
[](int k, coveo::enumerable<const std::string> e) { k + return e.begin()->size(); });
// res == { 29, 46, 71 }
Parameters
key_selKey selector, used to extract a key for a sequence element.
value_selValue selector, used to extract a value for a sequence element.
result_selResult selector, used to fold groups into final results.
Returns
(Once applied) Sequence of values returned by result_sel.

◆ group_values_by_and_fold() [2/2]

template<typename KeySelector , typename ValueSelector , typename ResultSelector , typename Pred >
auto coveo::linq::group_values_by_and_fold ( KeySelector &&  key_sel,
ValueSelector &&  value_sel,
ResultSelector &&  result_sel,
Pred &&  pred 
) -> detail::group_by_impl<KeySelector, ValueSelector, ResultSelector, Pred>

Scans the input sequence and, for each element, fetches a key using the provided key selector and a value using the provided value selector. Then, creates groups of values that have a common key and uses the provided result selector to convert the groups. The result selector is called with two arguments: a key, and a sequence of values matching that key. The final result is a sequence of the values returned by the result selector. The result selector is called in order of key, as determined by the provided predicate. The predicate must provide a strict ordering of the keys, like std::less.

Use like this:

const std::vector<std::pair<int, std::string>> DATA = {
{ 42, "Life" },
{ 23, "Hangar" },
{ 42, "Universe" },
{ 66, "Route" },
{ 23, "Jeep" },
};
using namespace coveo::linq;
auto res = from(DATA)
| group_values_by_and_fold([](std::pair<int, std::string> p) { return p.first; },
[](std::pair<int, std::string> p) { return p.second; },
[](int k, coveo::enumerable<const std::string> e) { k + return e.begin()->size(); },
[](int i, int j) { return i > j; });
// res == { 71, 46, 29 }
Parameters
key_selKey selector, used to extract a key for a sequence element.
value_selValue selector, used to extract a value for a sequence element.
result_selResult selector, used to fold groups into final results.
predPredicate used to compare the keys.
Returns
(Once applied) Sequence of values returned by result_sel.