Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq Distinct only in next rows match

Tags:

c#

.net

linq

I have a datatable with the following information:

365.00
370.00
369.59
365.00
365.00 -> match with previous item
365.00 -> match with previous item

I only need to remove the next matched items, like this:

365.00
370.00
369.59
365.00

I tried:

(from articlespricehistory in dt.AsEnumerable()
select new
{
   articlepricehistory_cost = articlespricehistory.Field<Double>("articlepricehistory_cost")
})
.DistinctBy(i => i.articlepricehistory_cost)
.ToList();

Result:

365.00
370.00
369.59

Any ideas?

like image 909
Jonathan Edgardo Avatar asked Oct 11 '15 22:10

Jonathan Edgardo


3 Answers

Here's an idea I have not actually tried

  • Do a Skip(1) on the query to produce a second query.
  • Now append to the second query any element not equal to the last element in the first query, to produce a third query.
  • Now zip join the first and third queries together to form a set of pairs; this is the fourth query.
  • Now construct a fifth query that filters out pairs that have identical elements from the fourth query.
  • Finally, construct a sixth query that selects the first element of each pair from the fifth query.

The sixth query is the data set you want.

like image 155
Eric Lippert Avatar answered Nov 06 '22 22:11

Eric Lippert


Here's a neat LINQ solution for u

var list = (dt as Enumerable);

var numbers = list.TakeWhile((currentItem, index) => currentItem != list.ElementAtOrDefault(index - 1));

Keep in mind if u have 0 as the first element it will be ommitted from the new list since ElementAtOrDefault will return 0 in the first iteration of the while loop (index of -1), thus evaluating the expression to false. A simple if statement can help you avoid this.

like image 28
kkyr Avatar answered Nov 06 '22 20:11

kkyr


The problem in your query is that you are using .DistinctBy() which will return distinct results only. So if 365.00 appeared anywhere, it won't show up in the returned list again.

var differentPreviousList = new List<double>();
var itemPriceList = dt.ToList();
differentPreviousList.Add(itemPriceList[0]);
for (var index = 1; index < itemPriceList.Count; index++)
{
    if (itemPriceList[index - 1] == itemPriceList[index]) continue;
    differentPriceList.Add(itemPriceList[index]);
}
like image 26
displayName Avatar answered Nov 06 '22 20:11

displayName