我有一个具有指定values.It的列表可以包含任何值。假设具有以下测试值。
1,1,1,5,5,4,4,1,1,1,3,3,3,3,3
我只需要找到连续的数字更改位置作为输出。例如,在上面的例子中,更改是1->5 then 5->4, 4->1 and 1->3.
,因此输出列表应该返回更改的位置,结果是4,6,8,11.
我可以通过比较连续的数字()轻松地遍历列表并找到位置,但是我想知道如何在linq中实现这一点。
发布于 2017-11-08 21:15:51
下面是这样做的一种方法,使用选择索引过载对项目编号,然后将相邻项(使用Skip(1)
)进行压缩,然后比较它们:
var items = "1,1,1,5,5,4,4,1,1,1,3,3,3,3,3".Split(',');
var itemsIndexed = items
.Select((n, idx) => (Value: n, Index: idx));
var result = itemsIndexed
.Zip(itemsIndexed.Skip(1), (l, r) => (Left: l, Right: r))
.Where(i => i.Left.Value != i.Right.Value)
.Select(i => i.Right.Index + 1);
+1是因为你似乎想要一个基于1的索引。
(我使用过ValueTuples --如果您使用的是旧版本的C#,请用Tuple.Create
代替)
当然,这不可能像命令式循环那样具有表现力!
发布于 2017-11-08 21:18:46
由于您希望使用linq来完成这项工作,所以首先需要创建另一个项和索引列表,然后使用前面的项检查当前项。如果不相等,则选择它。
var arr = new int[] { 1, 1, 1, 5, 5, 4, 4, 1, 1, 1, 3, 3, 3, 3, 3 };
var output = arr.Select((num, i) => new { Num = num, Index = i })
.Where((item, index) => index != 0 && item.Num != arr[index-1])
.Select(z => z.Index+1);
发布于 2017-11-08 21:28:21
另一种可能的解决办法是:
int[] nums = { 1, 1, 1, 5, 5, 4, 4, 1, 1, 1, 3, 3, 3, 3, 3 };
int[] changes = Enumerable.Range(1, nums.Length - 1).Where(i => nums[i - 1] != nums[i]).Select(i => i + 1).ToArray();
https://stackoverflow.com/questions/47194249
复制相似问题