score:1

Accepted answer

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], [3], [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], [3], [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};
> numbers.groupadjacentby(f)
[[6,-50,100], [190,200], [20]]

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)
            {
                partitions.add(new list<t>());
            }
            partitions.last().add(item);
        }
        else
        {
            partitions.add(new list<t> { item });
        }
        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)
        {
            indices.add(i);
            currentcategory = newcat;
        }
    }
    list<list<double>> collections = new list<list<double>>(indices.count);
    for (int i = 1; i < indices.count; ++i)
        collections.add(new list<double>(
            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);

Related Query

More Query from same tag