【问题标题】:Return TRUE for ALL when specific property is smaller then other property for both lists当两个列表的特定属性小于其他属性时,为 ALL 返回 TRUE
【发布时间】:2018-08-14 23:20:30
【问题描述】:

这很难解释,所以我在这里做了一个简化的数据示例:

我这里有 2 个不同复合体类型的列表:

列表1:

{ Id = 1 , Value = 1 }; {Id = 2 ,  Value = 2 }; { Id = 3 , Value = 1.5}

列表2

{ Id = 1 , Value = 1 }; {Id = 2 ,  Value = 2 }; { Id = 3 , Value = 1.5}

两个列表的比较应该返回 TRUE,因为 Value 属性的每个值在两个列表中都是相等的。

如果只有一个 Value 属性值不同,则整个结果必须为 FALSE。

如何使用首选 linq 来做到这一点?

【问题讨论】:

  • 标题中有“当特定属性小于其他属性时”和“两个列表中的值属性相等...如果只有一个值属性值不同,则整个结果必须为 FALSE 。”在你的身体里。什么是实际的比较逻辑?
  • 列表是否保证按 Id 排序?
  • 是否需要通过列表位置或ID查看对应的值?比较{ Id = 1 , Value = 1 }, { Id = 2 , Value = 2 }{ Id = 2 , Value = 1 }, { Id = 1 , Value = 2 } 的预期结果是什么?为什么?

标签: c# linq


【解决方案1】:

试试这个,使用 LINQ 的 Zip 方法:

var result = list1.Zip(list2, (l1, l2) => l1.Value == l2.Value).All(x => x);

【讨论】:

    【解决方案2】:

    如果您需要通过Id 属性执行此检查,那么GroupJoin 就是您要查找的内容。
    它可以让你通过选择器对两个不同的集合进行分组,然后加入它们:

    bool ComplexCollectionValuesAreEqual(List<ComplexItem1> list1, List<ComplexItem2> list2)
    {
        try
        {
            var grouped = list1.GroupJoin(list2, x => x.Id, x => x.Id, 
                (outer, inners) => outer.Value == inners.Single().Value);
    
            return grouped.All(x => x);
        }
        catch (InvalidOperationException) // for .Single() fail case
        {
            return false;
        }
    }
    

    您可以在 GroupJoin 的最后一个 lambda 中应用其他比较逻辑,例如 outer.Value &lt;= inners.Single().Value 以检查 item1 中的所有值是否等于或小于 item2 中的相应值。

    请注意,在此实现中,如果 list2 集合中没有具有此类 ID 的对象,它将返回 false。如果您总是排除它存在,您可能想要抛出异常。

    【讨论】:

    • 看来 OP 对 Value 属性的差异感兴趣,而不是 ID 属性的差异。您的解决方案可能具有所有相同的值,但 ID 不同,结果将为假,但 OP 期望为真,因为所有值都相等。 (至少这是我从问题中了解到的)
    • @Steve 我的解决方案检查Value 属性对于具有相同 ID 的两种不同类型的对象是否相等。正如我从 OPs 的问题中了解到的那样,这就是他想要的。让我们澄清一下。
    • 是的,我刚刚在问题本身中阅读了您的 cmets
    【解决方案3】:
    bool isTrue = list1.Select((z, i) => z.Id != list2[i].Id || z.Value != list2[i].Value).Count() == 0;
    

    如果集合没有排序

    bool isTrue = list1.Where(x =>  list2.First(y => y.Id == x.Id).Value != x.Value ).Count() == 0;
    

    如果项目不应该有重复并且计数应该相等

    bool isTrue = list1.Where(x => list2.First(y => y.Id == x.Id).Value == x.Value).Count() == list2.Count && list2.Count == list1.Count;
    

    【讨论】:

      猜你喜欢
      • 2016-11-30
      • 2019-09-02
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多