逗号分隔字符串列表上的交集操作

本文关键字:操作 列表 分隔 字符串 | 更新日期: 2023-09-27 18:23:58

我有一个逗号分隔的字符串列表,如下所示:

    List<string> IdList=new List<string>();

列表中的每个元素都有像一样的逗号分隔字符串

     1,2,4,5,6,7,8,10,12,15,16
     2,3,5,7,8,9,0,10,16,17
     4,5,89,12,13,1,2,3,6,7,10,16

我想在这个字符串列表上应用AND运算,这样我就可以得到如下输出:

      2,5,7,10,16

有没有有效的方法来实施交叉口操作?

逗号分隔字符串列表上的交集操作

您实际上正在寻找交集

如果不需要按数字顺序排列值,可以将每个字符串视为逗号分隔的值。从第一个列表开始,然后适当地相互交叉:

HashSet<string> set = new HashSet<string>(list[0].Split(','));
foreach (var item in list.Skip(1))
{
    set.IntersectWith(item.Split(','));
}
string result = string.Join(",", set);

完整样本代码:

using System;
using System.Collections.Generic;
using System.Linq;
class Test
{
    static void Main()
    {
        var list = new List<string>
        {
            "1,2,4,5,6,7,8,10,12,15,16", 
            "2,3,5,7,8,9,0,10,16,17",
            "4,5,89,12,13,1,2,3,6,7,10,16"
        };
        HashSet<string> set = new HashSet<string>(list[0].Split(','));
        foreach (var item in list.Skip(1))
        {
            set.IntersectWith(item.Split(','));
        }
        string result = string.Join(",", set);
        Console.WriteLine(result);
    }
}

结果(订单不保证):

2,5,7,10,16

我不知道"内存利用率较低",但我的第一次尝试是这样的(未经测试,在浏览器中编码,没有Visual Studio方便的yadda yadda):

Dictionary<int,int> occurences = new Dictionary<int,int>();
int numberOfLists = YourCollectionOfOuterLists.Count;
foreach (string list in YourCollectionOfOuterLists) {
    foreach (string value in list.Split(',')) {
        occurences[value] = ((occurences[value] as int) ?? 0) + 1;
    }
}
List<int> output = new List<int>();
foreach (int key in occurences.Keys) {
    if (occurences[key] == numberOfLists) {
        output.Add(key);
    }
}
return String.Join(output.Select(x => x.ToString()), ",");

编写更简洁的代码可能是非常可能的,但任何能实现您所追求的目标的东西都必须执行大致相同的步骤:决定所有列表中存在哪些元素(这有点不重要,因为列表的数量未知),然后用这些值创建一个新的列表。

如果您可以访问它,像Parallel.ForEach()这样的东西可能有助于至少在第二个循环(可能还有第一个循环,在适当的锁定/同步的情况下)减少wallclock的执行时间。

如果你想要的不是这个,请澄清你的问题,准确地描述你想要什么。

我不确定性能,但您可以使用Aggregate扩展方法来"折叠交叉点"。

var data = new List<string>
{
    "1,2,4,5,6,7,8,10,12,15,16",
    "2,3,5,7,8,9,0,10,16,17",
    "4,5,89,12,13,1,2,3,6,7,10,16",
};
var fold = data.Aggregate(data[0].Split(',').AsEnumerable(), (d1, d2) => d1.Intersect(d2.Split(',')));