【问题标题】:Compare two Lists by specific properties按特定属性比较两个列表
【发布时间】:2021-08-29 12:10:38
【问题描述】:

我在一个列表中有一个列表。我需要两个将 sub_List 的两个属性与第三个列表进行比较。

类:

public class Human
{
    public string FirstName{ get; set; }
    public string LastName{ get; set; }
    public List<Clothing> clothings { get; set; }
}

public class Clothing
{
    public string ClothingID{ get; set; }
    public string Garment{ get; set; }
    public string Color{ get; set; }
}

public class CurrentClothes
{
    public string Garment{ get; set; }
    public string Color{ get; set; }
}

伪代码:

public List<Human> humans = new List<Human>()
{
    new Human
    {
        FirstName="Karl",
        LastName="Karlson"
        clothings=new List<Clothing>()
        {
            new Clothing
            {
                ClothingID="1",
                Garment="T-Shirt",
                Color="pink"
            },
            new Clothing
            {
                ClothingID="11",
                Garment="Pant",
                Color="white"
            },
            new Clothing
            {
                ClothingID="111",
                Garment="Shoes",
                Color="black"
            }
        }
    },
    new Human
    {
        FirstName="Paula",
        LastName="Paulson"
        clothings=new List<Clothing>()
        {
            new Clothing
            {
                ClothingID="2",
                Garment="T-Shirt",
                Color="red"
            },
            new Clothing
            {
                ClothingID="22",
                Garment="Pant",
                Color="blue"
            },
            new Clothing
            {
                ClothingID="222"
                Garment="Shoes",
                Color="black"
            }
        }
    }
};
    
public List<CurrentClothes> currentclothes = new List<CurrentClothes>()
{
    new CurrentClothes
    {
        Garment="Pant",
        Color="blue"
    },
    new CurrentClothes
    {
        Garment="T-Shirt",
        Color="red"
    },
    new CurrentClothes
    {
        Garment="Shoes",
        Color="black"
    }
}

var human = humans.Where(x=>x.clothings.Equals(currentClothes));

问题是,我如何比较当前的衣服是否与某些人的衣服相匹配。有没有 Linq 选项?

我添加了一个示例。在此示例中,有两个人。卡尔和保拉。现在的衣服是确定的。现在我想要人类如何匹配当前的衣服。在这种情况下是宝拉。

【问题讨论】:

  • 你能给我们提供预期输出的样本数据吗?对我来说,这实际上很不清楚
  • Enumerable.Any 你在找什么?
  • 你叫什么“比较”你如何定义它们是否相等?也许你应该实现IEquatable
  • 您应该重写 Clothing 类的 Equals 方法。请参阅此处的文档,您将知道如何将其与 CurrentClothes 进行比较。 docs.microsoft.com/en-us/dotnet/api/… 。通过这种方式,您可以重新定义您的标准,了解如何始终比较这两个类并定义您的平等标准
  • @Zinov 您能否在我的示例中提供一个代码示例如何覆盖 equal 方法并使用 ist 从列表中获取正确的人?

标签: c# list linq ienumerable


【解决方案1】:

我会做以下事情

public class Human
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Clothing> clothings { get; set; }
}

public class Clothing : CurrentClothes
{
    public string ClothingID { get; set; }
}

public class CurrentClothes : IEquatable<CurrentClothes>
{
    public string Garment { get; set; }
    public string Color { get; set; }

    public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is CurrentClothes other && Equals(other);
    public bool Equals(CurrentClothes other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Garment == other.Garment && Color == other.Color;
    }
    public override int GetHashCode() => HashCode.Combine(Garment, Color);
}

比这样使用它:

var currentclothesAsHashSet = currentclothes.ToHashSet();
var human = humans.Where(x => x.clothings.OfType<CurrentClothes>().ToHashSet().SetEquals(currentclothesAsHashSet));
foreach (var human1 in human)
{
    Console.WriteLine(human1.FirstName);
}

这个使用的方法

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iset-1.setequals

查看Human.clothings 是否与currentclothes 相同。

这里有一个演示: https://dotnetfiddle.net/tS72Wt

编辑:

正如评论中所指出的,如果currentClothes 只能是数据的一个子集,您可能需要将SetEquals 更改为Except

就像这个演示演示的那样:

https://dotnetfiddle.net/FZg85Z

【讨论】:

  • 只是对@T0bi 的一个小评论,从目前的衣服与人类所穿的完全一样的问题中不清楚,如果不是并且当前的衣服可能指定比实际更多的衣服,你可以像这样使用 IsSupersetOf 而不是 SetEquals: ... var human = human.Where(x =>currentClothesAsHashSet.IsSupersetOf(x.clothings.OfType().ToHashSet()));
  • @DorLugasi-Gal - contains 是错误的,因为人类 Frank 和 Paula 都包含“Shoes / black”,只有 Paula 应该是阳性结果。 - 我唯一能看到的是 currentClothes 只是数据的一个子集,例如。只有 2 个条目,但人类有 3 个服装条目而不是 SetEquals 是错误的,它需要更改为 !subset.Except(superset).Any() - 就像这里解释的那样:stackoverflow.com/questions/407729/…
  • @DorLugasi-Gal,是的,可能还有更多,例如(示例 + 新衣服“Head”),那么它不匹配。
  • 我是否理解正确,如果我继承某些东西,我可以更改仅比较继承的相同方法?
  • @RandRandom 感谢您的回答和提供的示例。我检查了dotnetfiddle.net/FZg85Z 链接,我发现当我删除一个 currentclothing 对象时,它也显示了 paula。我现在就试一试,希望能找到解决问题的方法。
【解决方案2】:

你可以像这样使用Any

    humans.clothings.Where(x => 
       currentClothes.Any(s => 
        s.Color.Equals(x.Color) && s.Garment.Equals(x.Garment)
       )
    ).ToList();

查看this 获取 .netFiddle 演示

【讨论】:

  • 似乎不符合要求,因为您返回的是服装清单而不是人类。并且似乎Any 不正确,更像是只返回返回与ALL 衣服匹配的人
  • 我知道,我会更新这个@RandRandom
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 2020-04-10
相关资源
最近更新 更多