【问题标题】:Find common items in list of lists of strings在字符串列表列表中查找常见项目
【发布时间】:2014-12-09 15:44:57
【问题描述】:

您好,我有包含字符串列表的 allLists 我想在这些字符串列表中找到常见项目 我试过了

var intersection = allLists
  .Skip(1)
  .Aggregate(
  new HashSet<string>(allLists.First()),
  (h, e) => { h.IntersectWith(e); return h);`

还有交集(按索引的硬代码列表)当我尝试时它们都不起作用

var inter = allLists[0].Intersect(allLists[1]).Intersect(allLists[2])
     .Intersect(allLists[3]).ToList();

foreach ( string s in inter) Debug.WriteLine(s+"\n ");

那么我将如何动态地执行此操作并在列表中获取常见的字符串项; 有没有办法避免 Linq?

【问题讨论】:

标签: c# linq


【解决方案1】:

这不是最简单的方法吗?

var stringLists = new List<string>[] 
    { 
        new List<string>(){ "a", "b", "c" },
        new List<string>(){ "d", "b", "c" },
        new List<string>(){ "a", "e", "c" }
    };

var commonElements =
    stringLists
        .Aggregate((xs, ys) => xs.Intersect(ys).ToList());

我得到一个列表,其中只有 "c"

如果每个列表中的元素可以重复,这也可以处理这种情况。

【讨论】:

  • 这可能会更短,但如果您需要 Intersect 的不同条件,则使用 GroupBy 更容易,然后编写自定义 IEqualityComparer... 这不是最简单的方式了。
【解决方案2】:

我会这样做:

class Program
{
    static void Main(string[] args)
    {
        List<string>[] stringLists = new List<string>[] 
        { 
            new List<string>(){ "a", "b", "c" },
            new List<string>(){ "d", "b", "c" },
            new List<string>(){ "a", "e", "c" }
        };

        // Will contian only 'c' because it's the only common item in all three groups.
        var commonItems = 
            stringLists
            .SelectMany(list => list)
            .GroupBy(item => item)
            .Select(group => new { Count = group.Count(), Item = group.Key })
            .Where(item => item.Count == stringLists.Length);

        foreach (var item in commonItems)
        {
            Console.WriteLine(String.Format("Item: {0}, Count: {1}", item.Item, item.Count));
        }
        Console.ReadKey();
    }
}

如果一个项目出现在所有组中,则它是一个公共项目,因此它的计数必须等于组的数量:

.Where(item => item.Count == stringLists.Length)

编辑:

我应该在问题中使用HashSet。对于列表,您可以将 SelectMany 行替换为这一行:

.SelectMany(list => list.Distinct())

【讨论】:

  • 如何获取 commonItems?我试过foreach(commonitems中的字符串ss)它说无法将匿名转换为字符串
  • commonItems 中的每个项目都是一个匿名对象,其属性 CountItem 就像在 Select 中定义的一样。我编辑了答案并添加了一个循环。您可以随意命名属性。这只是一个例子。
  • 我应该像问题中那样采用HashSet。我无法解释为什么我选择了List,但我吃的是前者。或者您只需要列表中的SelectMany 中的Distinct
猜你喜欢
  • 2022-01-25
  • 2020-02-23
  • 2019-04-25
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 2015-10-05
相关资源
最近更新 更多