score:1

Your example is complicated. I'll first state and solve a simpler problem, then use the same method to solve your original problem.

I want to split a list of numbers into contiguous groups of even and odd numbers. For example, given the list `2,2,4,3,6,2` I would split it into three groups `[2,2,4], , [6,2]`

This can be done concisely with a GroupAdjacentBy method

``````> var numbers = new List<int>{2,2,4,3,6,2};
> numbers.GroupAdjacentBy(x => x % 2)
[[2,2,4], , [6,2]]
``````

To solve your problem, simply replace the even-odd classifying function above with your classification function:

``````> var points = new List<int>{-180,180};
> var f = new Func<int,int>(x => points.BinarySearch(x));
> var numbers = new List<int>{6,-50,100,190,200,20};
[[6,-50,100], [190,200], ]
``````

score:0

If you need the collections to be updated as soon as the values change why don;t you use properties? Something like

``````// your original collection
public IList<double> OriginalValues; //= new List<double> { -1000, 5, 7 1000 };

public IList<double> BelowMinus180
{
get { return OriginalValues.Where(x => x < -180).ToList().AsReadOnly(); }
}

public IList<double> BetweenMinus180And180
{
get { return OriginalValues.Where(x => x >= -180 && x <= 180).ToList().AsReadOnly(); }
}

public IList<double> Above180
{
get { return OriginalValues.Where(x => x > 180).ToList().AsReadOnly(); }
}
``````

score:0

``````public static List<List<T>> PartitionBy<T>(this IEnumerable<T> seq, Func<T, bool> predicate)
{
bool lastPass = true;
return seq.Aggregate(new List<List<T>>(), (partitions, item) =>
{
bool inc = predicate(item);
if (inc == lastPass)
{
if (partitions.Count == 0)
{
}
}
else
{
}
lastPass = inc;
return partitions;
});
}
``````

You can then use:

``````List<List<double>> segments = newDataSet.PartitionBy(d => d > -180 && d < 180);
``````

score:0

How about this possible solution using two passes. In the first pass we find the indices were a change occurs, and in the second pass we do the actual partitioning. First an auxiliary method to determine the category:

``````    protected int DetermineCategory(double number)
{
if (number < 180 && number > -180)
return 0;
else if (number < -180)
return 1;
else
return 2;
}
``````

And then the actual algorithm:

``````    List<int> indices = new List<int>();
int currentCategory = -1;
for (int i = 0; i < numbers.Count; i++)
{
int newCat = DetermineCategory(numbers[i]);
if (newCat != currentCategory)
{
currentCategory = newCat;
}
}
List<List<double>> collections = new List<List<double>>(indices.Count);
for (int i = 1; i < indices.Count; ++i)
numbers.Skip(indices[i - 1]).Take(indices[i] - indices[i - 1])));
``````

score:0

Here is a new answer based on the new info you provided. I hope this time I will be closer to what you need

``````public IEnumerable<IList<double>> GetCollectionOfCollections(IList<double> values, IList<double> boundries)
{
var ordered = values.OrderBy(x => x).ToList();
for (int i = 0; i < boundries.Count; i++)
{
var collection = ordered.Where(x => x < boundries[i]).ToList();
if (collection.Count > 0)
{
ordered = ordered.Except(collection).ToList();
yield return collection.ToList();
}
}
if (ordered.Count() > 0)
{
yield return ordered;
}
}
``````

score:0

One method with linq. Untested but should work

``````var firstSet = dataSet.TakeWhile(x=>x>-180&&x<180);
var totalCount = firstSet.Count();
var secondSet = dataSet.Skip(totalCount).TakeWhile(x=>x<-180);
totalCount+=secondSet.Count();
var thirdSet = dataSet.Skip(totalCount).TakeWhile(x=>x>180);
totalCount += thirdSet.Count();
var fourthSet = dataSet.Skip(totalCount);
``````