c#根据子项比较两个列表并返回差异

时间:2016-10-24 09:16:56

标签: c# linq

我需要帮助构建一个linq查询以返回列表中缺少的子项。

我有一个包含类的项目列表,如下所示

class Tags
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Items
{
    public string Name { get; set; }
    public List<Tags> TagList { get; set; }
}

现在我有2个列表OldItemList和NewItemList,我需要获取OldItemList中NewItemList中缺少类别的所有项目。

EG。 OldItemList AApple - tags =&gt;水果,有机 BApple - tags =&gt;水果,有机

NewItemList AApple - tags =&gt;水果,富士 BApple - tags =&gt;水果,有机

查询应该返回text =&gt; &#39; Apple缺少标签Organic&#39;

我可以从以下查询中获取AApple,我需要帮助来获取缺少的标记

var missingItems = from oldItem in OldItemList
                   join newItem in NewItemList on oldItem.Name equals newItem.Name
                   where oldItem.TagList.Any(tagList1 => !newItem.TagList.Any(tagList2 => tagList1.Id == tagList2.Id))
                   select oldItem.Name;

整个代码

class Tags
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Items
{
    public string Name { get; set; }
    public List<Tags> TagList { get; set; }
}
public class LinqTest
{
    public static void Test1()
    {
        List<Items> OldItemList = new List<Items>(){
        new Items
        {
            Name="A",
            TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=2, Name="2"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
        } ,
        new Items
        {
            Name="B",
            TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=2, Name="2"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
        } ,
        new Items
        {
            Name="C",
            TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=2, Name="2"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
        } ,
        new Items
        {
            Name="D",
            TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=2, Name="2"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
        }
       };


        List<Items> NewItemList = new List<Items>()
        {
            new Items
            {
                Name="A",
                TagList = new List<Tags>{ new Tags { Id = 12, Name = "1" }, new Tags{Id=2, Name="2"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
            } ,
            new Items
            {
                Name="B",
                TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=3, Name="3"}, new Tags{Id=4, Name="4"}}
            } ,
            new Items
            {
                Name="D",
                TagList = new List<Tags>{ new Tags{Id=1, Name="1"}, new Tags{Id=2, Name="2"}, new Tags{Id=4, Name="4"}}
            }
        };

        //To find missing items in variables
        var missingItems = from oldItem in OldItemList
                           join newItem in NewItemList on oldItem.Name equals newItem.Name
                           where oldItem.TagList.Any(tagList1 => !newItem.TagList.Any(tagList2 => tagList1.Id == tagList2.Id))
                           select oldItem.Name;

        foreach (string var in missingItems)
        {
            Console.WriteLine("var => " + var);
        }
    }

}

从以下评论中回答

        var missingItems = from oldItem in OldItemList
                           join newItem in NewItemList on oldItem.Name equals newItem.Name
                           let missingTags = oldItem.TagList.Where
                            (oldTag => !newItem.TagList.Any(newTag => oldTag.Id == newTag.Id))
                           where missingTags.Any()
                           select new { Item = newItem.Name, MissingTags = missingTags.ToList() };

2 个答案:

答案 0 :(得分:0)

我可以理解该问题,您可以使用此查询 -

  var missingItems = from oldItem in OldItemList
               join newItem in NewItemList on oldItem.Name equals newItem.Name
               where oldItem.TagList.Any(tagList1 => !newItem.TagList.Any(tagList2 => tagList1.Id == tagList2.Id))
               select new string{ oldItem.Name + " missing tag " + 
               String.Join(",",oldItem.TagList.Any(tagList1 => !newItem.TagList.Any(tagList2 => tagList1.Id == tagList2.Id)).Select(taglist=>taglist.Name))};

目前我没有使用任何IDE,所以如果有任何错误,请更新我。

答案 1 :(得分:0)

您可以尝试为let子句中的每个新项选择所有缺少的标记,如果有任何缺少的标记,您可以选择它们,并使用匿名类型的项:

var missingItems = from oldItem in OldItemList
                   join newItem in NewItemList on oldItem.Name equals newItem.Name
                   let missingTags = oldItem.TagList.Where(oldTag => !newItem.TagList.Any(newTag=> oldTag.Id == newTag.Id))
                   where missingTags.Any()
                   select new { Item = newItem, MissingTags = missingTags };