我有一个逗号分隔的字符串列表,如下所示:
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
有没有有效的方法来实施交叉口操作?
答案 0 :(得分:4)
您实际上正在寻找交叉点。
如果您不需要按数字顺序排列值,则可以将每个字符串视为逗号分隔值。从第一个列表开始,然后恰当地相互交叉:
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
答案 1 :(得分:2)
我不知道“内存利用率较低”,但我对此的第一次尝试将是这些内容(未经测试,在浏览器中编码,没有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()
之类的内容可能有助于减少至少第二个循环的挂钟执行时间(可能是第一个循环,并且正确锁定/同步到位)。
如果您正在接受除此之外的其他事情,请澄清您的问题以准确描述您想要的内容。
答案 2 :(得分:0)
我不确定效果,但您可以使用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(',')));