From 8d9b3c6e7f72e8eb1044347f848ba38176aef31d Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sat, 9 Jan 2016 18:27:02 +0000 Subject: [PATCH] CSequence::separate splits up a sequence into a map of sequences categorized by some predicate. --- src/blackmisc/sequence.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/blackmisc/sequence.h b/src/blackmisc/sequence.h index 3d0685474..c50011924 100644 --- a/src/blackmisc/sequence.h +++ b/src/blackmisc/sequence.h @@ -578,6 +578,33 @@ namespace BlackMisc return partiallySorted(n, BlackMisc::Predicates::MemberLess(key1, keys...)); } + /*! + * Split up the sequence into subsequences for which the given predicate returns the same value. + */ + template + auto separate(Predicate p) const -> QMap())), CSequence> + { + QMap())), CSequence> result; + auto copy = *this; + std::stable_sort(copy.begin(), copy.end(), [p](const T &a, const T &b) { return p(a) < p(b); }); + for (auto it = copy.cbegin(); it != copy.cend(); ) + { + auto mid = std::adjacent_find(it, copy.cend(), [p](const T &a, const T &b) { return p(a) != p(b); }); + result.insert(p(*it), makeRange(it, mid)); + it = mid; + } + return result; + } + + /*! + * Split up the sequence into subsequences of elements having the same value for the given key. + */ + template + auto separateBy(Key k) const -> QMap().*k), CSequence> + { + return separateBy([k](const T &v) { return v.*k; }); + } + //! Equals operator. friend bool operator ==(const CSequence &a, const CSequence &b) {