C#Linq to Objects / Syntax并有效地搜索集合成员是否存在于另一个子集合集合中

时间:2011-09-23 07:10:30

标签: c# search hyperlink

我有第一批数字:(1,3,5,6,23)

和第一个1到n个整数的集合集合

(3),    (6,1),    (1,3,5,23,6,14,67),    (2,3)

所以第二个集合有元素a,b,c和d,它们本身就是整数的集合

a=(3), b=(6,1), c=(1,3,5,23,6,14,67), d=(2,3)

所以这基本上是一个锯齿状的数组)

如何使用扩展方法语法和查询表达式语法对Linq进行对象查询 找出第一个集合中的数字组合可以在a,b,c或d或无处的集合中找到。换句话说,第二个集合中的哪些数字包含在第一个集合中。

Q1:我希望看到a=(3), b=(6,1)被发现,因为每个集合的成员a和b c都存在于第一个集合中。

Q2:我希望看到相反的情况,我们从第二个集合开始,并尝试查找其子集合成员是否属于第一个集合。

我想了解这两种方法的优缺点。实际上,我将处理数千个集合,每个集合最多包含10个数字。

2 个答案:

答案 0 :(得分:1)

这样的东西?

int[] firstSet = new[] { 1,3,5,6,23 };
int[][] secondSet = new[] 
{
    new [] { 3 },
    new [] { 6, 1 },
    new [] { 1,3,5,23,6,14,67 },
    new [] { 2, 3}
};

// only subsets where each member matces a member of the first set
var matchinSubSets = from subset in secondSet
                     where subset.All(x => firstSet.Contains(x))
                     select subset;

至于表现,不要太担心,如果你只是要匹配成千上万的参赛作品,那么在你知道它之前就会完成计算

答案 1 :(得分:1)

你走了。试试这些:

var xs = new [] { 1, 3, 5, 6, 23, };
var yss = new []
{
    new [] { 3, },
    new [] { 6, 1, },
    new [] { 1, 3, 5, 23, 6, 14, 67, },
    new [] { 2, 3, },
};

我先回答你的第二个问题:

var q2 =
    from ys in yss
    where !ys.Except(xs).Any()
    select ys;

var q2b = yss.Where(ys => !ys.Except(xs).Any());

这两个查询是相同的 - 除了一个在LINQ中,另一个在扩展方法语法中。编译器将为两者生成相同的代码。

问题一是噩梦 - 更难做到。

var q1 =
    from z in yss.Zip(
        xs.Aggregate(
            yss.AsEnumerable(),
            (_yss, x) => (
                from ys in _yss
                select ys.Except(new [] { x }).ToArray())),
        (ys, _ys) => new { ys, _ys })
    where !z._ys.Any()
    select z.ys;

var q1b =
    yss.Zip(
        xs.Aggregate(
            yss.AsEnumerable(),
            (_yss, x) => _yss
                .Select(ys =>
                    ys.Except(new [] { x }).ToArray())),
        (ys, _ys) => new { ys, _ys })
    .Where(z => !z._ys.Any())
    .Select(z => z.ys);

同样在LINQ和扩展方法语法中都编译为相同的代码。

我运行了一些性能测试,“q2”查询比“q1”查询快了10倍以上。

在一次测试中,我有xs有61个不同的元素,yss有100,000个不同的有价值的子集合,总共有956,512个元素,“q1”查询在5,354.1毫秒内运行& “q2”在302.1毫秒内运行 - 17.7倍因子。

然而,将其降至10 {和1}的xsyss 10,000& 95,641然后结果是115.3&分别为7.4毫秒。这两种方法都可能足够快。