I have a list of items (List<Tasks> tasks
), like this one:
Id Action Source Target
------- --------- -------- ---------
1 Save 12 18
4 Save 18 21
7 Save 21 23
6 Save 23 25
10 Save 25 27
16 Save 29 31
0 Edit 31 37
What I want to do, is to merge the rows that have the same (Source
and Target
) and the same Action
. For example, what I need at the end should look like this:
Id Action Source Target
------- --------- -------- ---------
22 Save 12 27
16 Save 29 31
0 Edit 31 37
Which means, all the items that have the same Action
(in my case here Save) should be merged to one row/item but only in case the Target
value of the upper item is equal to the Source
value of the follower item. A follower is the lower item.
For example, upper is item Id = 1
and lower/follower is item Id = 4
. So the record that follows.
Is there any way to do this with linq avoiding the too many foreach loops? Maybe something like Hierarchies with CTE in SQL. But I'm still not finding the correct syntax, so that's why I didn't paste any code.
Thanks in advance!
If you want "LINQ" solution, you can use Aggregate
like this:
var result = tasks.Aggregate(new List<Item>(), (acc, current) =>
{
if (acc.Count > 0)
{
var prev = acc[acc.Count - 1];
if (prev.Action == current.Action && prev.Target == current.Source)
{
// update previous target
prev.Target = current.Target;
}
// otherwise just add
else acc.Add(current);
}
else acc.Add(current);
return acc;
});
It starts with empty List
as accumulator, and feeds items one by one. Then we just add items to accumulator if they do not match criteria, and if they do match - we update previous item instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With