Linq过滤帖子按标签列表

时间:2016-08-18 15:52:16

标签: linq

public class LogItemTag
{
    public int ID { get; set; }
    public string Tagname { get; set; }
}

var logItemTags = new List<LogItemTag>();
logItemTags.Add(new LogItemTag { ID = 1, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 1, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "blue" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 4, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 6, TagName = "white" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "green" });

var listOfTagsToFilterOn = new List<string> {"red", "green" };

//I need a list of ids 1 and 7 only.

//this query produces 6 ids - 1,1,3,4,7,7
var query = logItemTags.Where(lit => listOfTagsToFilterOn.Contains(lit.TagName)).Select(lit => lit.ID).ToList();

3 个答案:

答案 0 :(得分:2)

使用Contains扩展方法:

var tags=new List<string>(){"red", "green"};// the collection of tags you want to get the ids
var query=LogItemTagList.Where(l=>tags.Contains(l.Tagname)).Select(l=>l.ID);

更新1

我认为这是你想要实现的目标:

var query=LogItemTagList.Where(l=>tags.Contains(l.Tagname))
                        .GroupBy(l=>l.ID)
                        .Where(g=>g.Count==tags.Count)
                        .Select(g=>g.Key)
                        .ToList();

答案 1 :(得分:2)

使用Enumerable.Contains扩展方法

var filterList = new [] {"red", "green"};
var list = new List<LogItemTag>
       {
             new LogItemTag {ID =1; TagName = "green"},
             ....
       };

var filteredIds = list.Where(i => filterList.Contains(i.TagName)
                  .Select(f => f.ID).ToList();

<强>更新

List<LogItemTag> logItemTags = new List<LogItemTag>();
logItemTags.Add(new LogItemTag { ID = 1, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 1, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "blue" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 4, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 6, TagName = "white" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "green" });

var listOfTagsToFilterOn = new List<string> {"red", "green" };

var filteredList = logItemTags.Where(l => listOfTagsToFilterOn.Contains(l.TagName))
    .GroupBy(l => l.ID,
             l => l.TagName,
             (k, t) => new {Id = k, Count = t.Distinct().Count()})
    .Where(d => d.Count == listOfTagsToFilterOn.Count())
    .Select(d => d.Id).ToList();

这里有一些解释

首先,我们按ID对数据进行分组,并生成具有ID和不同标记数的匿名类型的对象。然后过滤它们以匹配标记计数以过滤标记计数。这可以用于将相同的标记设置为sme ID。

答案 2 :(得分:1)

我就是这样做的。随意编辑/优化它。

var logItemTags = new List<LogItemTag>();
logItemTags.Add(new LogItemTag { ID = 1, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 1, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "blue" });
logItemTags.Add(new LogItemTag { ID = 3, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 4, TagName = "green" });
logItemTags.Add(new LogItemTag { ID = 6, TagName = "white" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "red" });
logItemTags.Add(new LogItemTag { ID = 7, TagName = "green" });

var listOfTagsToFilterOn = new List<string> {"red", "green" };

var list = logItemTags.Where(
    x => listOfTagsToFilterOn.All(
    y => logItemTags.Any(
    z => z.ID == x.ID && y.TagName == z.TagName)))
    .Select(x => x.ID).Distinct();

选择所有通过所有过滤器的ID(项目包含所有标记名)