user613326
user613326

Reputation: 2180

Linq get list of indexes matching a condition to filter another list against

I've got a list as a result of some pixel math like:

List<double> MList = new List<double>(new double[]{ 0.002, 0.123, 0.457, 0.237 ,0.1});

I would like to use Linq, to retrieve from that list, all indexes of items below a value, so if the value to compare against is 0.15 it sould result the folowing indexes : 0,1,4

List<double> MClose = new list<double>();
double compare = 0.15;
List<double> MClose = MList.Where(item => item < compare).Select((item,index) => index);

I hope so far so good, then i would like to use this gained index, to use against another list. That's a list made out of RGB values, to build a new list only out of values selected by that index.

class RGB{int r;int g; int b}
list<RGB>=colors = new RGB(){new RGB[,,]{{10,10,2},{13,11,2},{15,16,17},{33,13,2},{35,116,117}}};

I don't have used Linq a lot, and I wonder if this could be coded trough Linq, maybe even a one liner ?, i'm curious how small an answers could get. And (would Linq be fast for pixel editing), i'm dealing width convulsion maps here usually 3x3 to 64x64 pixels of data.

Upvotes: 3

Views: 5807

Answers (3)

zola25
zola25

Reputation: 1921

List<double> MClose = MList.Where(item => item < compare).Select((item,index) => index);

First you've defined MClose to be a List<double> but your final .Select((item,index) => index) will return an IEnumerable<int> - which isn't a List but a collection that can be iterated over. Use var to automatically infer the type of MClose, and use .ToList() so that the result of the iteration is only evaluated once and brought into memory:

var MClose = MList.Where(item => item < compare).Select((item,index) => index).ToList();

Then you can use the .Where clause with indexes:

var filteredColors = colors.Where((c,index)=> MClose.Contains(index)).ToList();

Use .Contains() to filter only those indexes that you've got in MClose.

Upvotes: 4

Aleks Andreev
Aleks Andreev

Reputation: 7054

You need to reorder your linq methods. First call Select then When:

List<double> MList = new List<double>(new double[] { 0.002, 0.123, 0.457, 0.237, 0.1 });
double compare = 0.15;
var idx = MList.Select((x, i) => new {x, i})
    .Where(x => x.x < compare)
    .Select(x => x.i)
    .ToArray();

Now in idx you will have [0, 1, 4]

Some explanations: after your are applying Where method, your indices will differ from originals. So first you need to save original index, then you may filter MList

Upvotes: 2

koryakinp
koryakinp

Reputation: 4125

I would like to use Linq, to retrieve from that list, all indexes of items below a value, so if the value to compare against is 0.15 it sould result the folowing indexes : 0,1,4

You can get an index of the element by using IndexOf()

List<double> list = new List<double> { 0.002, 0.123, 0.457, 0.237, 0.1 };
List<int> indexes = list
    .Where(q => q < 0.15)
    .Select(q => list.IndexOf(q))
    .ToList();

I hope so far so good, then i would like to use this gained index, to use against another list. That's a list made out of RGB values, to build a new list only out of values selected by that index.

Does not make much sense for me.

Upvotes: 0

Related Questions