查找键重复但值不同的项目

时间:2019-03-29 16:18:28

标签: c#

我有一个包含多个项目的列表。每个项目包含三个副词。 ID,名称,值。我只需要获取ID和Name相等但值不同的项目即可。

public class MyModel
{
    public int ElementID { get; set; }
    public string ElementName { get; set; }
    public string ElementValue { get; set; }
}

public class Program
{
    static void Main(string[] args)
    {

        var list = new List<MyModel>();

        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name1", ElementValue = "Id1Name1Value1"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name1", ElementValue = "Id1Name1Value2"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name2", ElementValue = "Id1Name2Value1"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name3", ElementValue = "Id1Name3Value1"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name3", ElementValue = "Id1Name3Value2"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name4", ElementValue = "Id1Name4Value1"});
        list.Add(new MyModel {ElementID = 1, ElementName = "Id1Name4", ElementValue = "Id1Name4Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name1", ElementValue = "Id2Name1Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name1", ElementValue = "Id2Name1Value2"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name2", ElementValue = "Id2Name2Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name3", ElementValue = "Id2Name3Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name3", ElementValue = "Id2Name3Value2"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name4", ElementValue = "Id2Name4Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name5", ElementValue = "Id2Name5Value1"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name5", ElementValue = "Id2Name5Value2"});
        list.Add(new MyModel {ElementID = 2, ElementName = "Id2Name5", ElementValue = "Id2Name5Value3"});

        //Expected output
        //Id1Name1Value1
        //Id1Name1Value2
        //Id1Name3Value1
        //Id1Name3Value2
        //Id2Name1Value1
        //Id2Name1Value2
        //Id2Name3Value1
        //Id2Name3Value2
        //Id2Name5Value1
        //Id2Name5Value2
        //Id2Name5Value3
    }


}

我没有正确使用lambda表达式。我可以对其进行分组,但是我无法找出最好的方法来仅过滤出ElementID和ELementName组中ElementValue不同的项目。

我想解决方案非常简单,但是我被困住了...

感谢所有帮助。

感谢“ vc 74”,我可以使用您的代码来使用它!。

var foo = list.GroupBy(i => 
    new
    {
        i.ElementID,
        i.ElementName
    }).
    Where(g => g.Select(i => i.ElementValue).Distinct().Count() > 1);

 foreach (var item in foo)
            {
                Console.WriteLine(item.Key.ElementName);

                foreach (var myModel in list.Where(x => x.ElementID == item.Key.ElementID && x.ElementName == item.Key.ElementName).ToList())
                {
                    Console.WriteLine($"  {myModel.ElementValue}");
                }

            }

            Console.ReadLine();

这很明显,每个组的ElementValue上的区别都达到了目的。我将创建一个扩展方法,该方法将返回包含重复项但值不同的项的列表。我正在考虑一个通用版本,您可以在其中定义对象上应作为组的哪些属性以及将哪些属性用作值。也许您可以在属性上使用“属性”来定义是在组中使用还是将其用作值。我们将会看到...

2 个答案:

答案 0 :(得分:3)

要选择具有多个值的ID /名称组合,请执行以下操作:

list.GroupBy(i => 
    new
    {
        i.ElementID,
        i.ElementName
    }).
    Where(g => g.Select(i => i.ElementValue).Distinct().Count() > 1);

请注意,这会返回包含您要查找的项目的组,每个组都有其项目。

Fiddle

答案 1 :(得分:0)

对于像这样的简单问题,您可以使用类似这样的东西:

        list.GroupBy(x => x.ElementValue).Select(grp => grp.First());
        list.ForEach(x => Console.WriteLine(x.ElementValue));

这为我带来了输出

enter image description here

您需要考虑的最大事情是,如果要进行很多相等比较,则应创建一个自定义IEqualityComparer类,并确保正确实现GetHashCode方法。