I need help in constructing a linq query to return missing sub items in the list.
I have a list of Items with classes as below
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; }
}
Now I have 2 list OldItemList and NewItemList and I need to get all Items in OldItemList which have category(s) missing from NewItemList.
Eg. OldItemList AApple - tags => fruit, Organic BApple - tags => fruit, Organic
NewItemList AApple - tags => fruit, Fuji BApple - tags => fruit, Organic
The query should return me text => 'AApple missing tag Organic' .
I could get AApple out of the below query and i need help to get the missing tags
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;
whole code
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);
}
}
}
Answer from below comments
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() };
As I can understand the Issue , you can use this query-
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))};
For now I am not using any IDE so if there is any typo just update me.
You can try to select all the missing tags for every new item in a let clause, if there is any missing tags you can select them and the item in an anonymous type:
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 };
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.