如何使用LINQ比较其先前值中的一个值?

时间:2014-08-15 22:24:54

标签: c# .net linq list

以下代码:

        Dictionary<int, List<int>> dic = new Dictionary<int, List<int>>();
        dic.Add(1, new List<int>());
        dic[1].Add(10);
        dic[1].Add(6);
        dic.Add(2, new List<int>());
        dic[2].Add(9);
        dic[2].Add(7);
        dic[2].Add(7);
        dic.Add(3, new List<int>());
        dic[3].Add(9);
        dic[3].Add(10);
        dic[3].Add(9);
        dic.Add(4, new List<int>());
        dic[4].Add(6);

        // Will give KVPs of Key 1 and 4
        var under7 = dic.Where(T => T.Value.Any(Y => Y < 7));

所以我很容易发现哪些KVP的值低于7。

我的问题是如何迭代字典以查找具有重复值的KVP,其中一个键跟随另一个键(已按顺序)。

因为这应该被拿起来:

        dic.Add(2, new List<int>());
        dic[2].Add(9);
        dic[2].Add(7); // MATCH
        dic[2].Add(7); // MATCH

但不是这样:

        dic.Add(3, new List<int>());
        dic[3].Add(9); // NOT MATCH
        dic[3].Add(10);
        dic[3].Add(9); // NOT MATCH

有没有办法用LINQ做到这一点?

试图用下面的东西试一试,但很明显它并没有这样做。

        // Should give KVP of Key 2 but not 3
        var dupVals = dic.Where(T => T.Value.Aggregate( (i1, i2) => i1 == i2));
        var dupVals = dic.Where(T => T.Value.Any( (i1,i2) => i1 == i2  ));

编辑: 谢尔盖得到了答案:

            var result = dic.Where(kvp =>
            kvp.Value.Skip(1).Zip(kvp.Value, (x, y) => x == y).Any(b => b));

但这究竟是如何运作的?

1 个答案:

答案 0 :(得分:7)

您可以使用

检查列表是否有两个连续的重复项
list.Skip(1).Zip(list, (x,y) => x == y).Any(b => b)

对字典中的每个值执行此操作:

// yep, you can use this pretty initializer
var dic = new Dictionary<int, List<int>> {
    { 1, new List<int> { 10, 6 }},
    { 2, new List<int> { 9, 7, 7 }},
    { 3, new List<int> { 9, 10, 9 }},
    { 4, new List<int> { 6 }}
};

var result = dic.Where(kvp =>
       kvp.Value.Skip(1).Zip(kvp.Value, (x, y) => x == y).Any(b => b));

说明:Enumerable.Zip扩展将指定函数(x,y) => x == y应用于两个序列的相应元素。这两个序列是列表,并且相同的列表向前移动了一个项目。即您正在将函数应用于同一列表的indexindex + 1项。此功能生成项目比较结果。因此,Zip将返回truefalse的序列,具体取决于连续项的相等性。如果结果中有true,那么您有两个连续的重复项。

分步示例:请考虑以下列表9, 10, 9, 7, 7。如果您跳过此列表中的第一项,您将获得序列10, 9, 7, 7。压缩这两个序列将产生以下项目对(您应该拍摄相应的项目 - 第一,第一,第二和第二等):(10, 9), (9, 10), (7,9), (7,7)。下一步是将(x,y) => x == y函数应用于每对。结果将为false, false, false, true。如您所见,最后一对(第一个序列中的第四个项目和第二个序列中的第四个项目)具有相同的项目,因此它生成true。最后一件事是检查是否有任何一对产生了true