Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查一个列表是否包含另一个列表_C#_.net - Fatal编程技术网

C# 如何检查一个列表是否包含另一个列表

C# 如何检查一个列表是否包含另一个列表,c#,.net,C#,.net,在c语言中,有没有优雅的方法来检查一个列表是否包含类似string.Containsstring的子列表 例如,我想测试列表A是否包含在列表B中 重要的是,所有元素必须完全按照该顺序匹配 我知道我可能会做类似的事情 bool Contains(List<Sampletype> source, List<Sampletype> sample) { // sample has to be smaller or equal length if (sample.C

在c语言中,有没有优雅的方法来检查一个列表是否包含类似string.Containsstring的子列表

例如,我想测试列表A是否包含在列表B中

重要的是,所有元素必须完全按照该顺序匹配

我知道我可能会做类似的事情

bool Contains(List<Sampletype> source, List<Sampletype> sample)
{
    // sample has to be smaller or equal length
    if (sample.Count > source.Count) return false;

    // doesn't even contain first element
    if (!source.Contains(sample[0])) return false;

    // get possible starts
    // see https://stackoverflow.com/a/10443540/7111561
    int[] possibleStartIndexes = source.Select((b, i) => b == sample[0] ? i : -1).Where(i => i != -1).ToArray();

    foreach (int possibleStartIndex in possibleStartIndexes)
    {
        // start is too late -> can't match
        if (possibleStartIndex + sample.Count - 1 > source.Count - 1) return false;

        for (int index = possibleStartIndex; index < possibleStartIndex + sample.Count; index++)
        {
            // if one element does not match the whole sample doesn't match
            if (source[index] != sample[index]) return false;
        }

        // if this is reached all elements of the sample matched
        Debug.Log("Match found starting at index " + possibleStartIndex);
        return true;
    }

    return false;
}
但我希望有更好的方法来做到这一点。

这里有一条单行线:

var result = A.Select(a => $"{a}").Aggregate((c, n) => $"{c};{n}").Contains(B.Select(b => $"{b}").Aggregate((c, n) => $"{c};{n}"));
它基本上从每个列表创建一个字符串,并检查a字符串是否包含B字符串。这样,您不仅可以获得string.Contains这样的方法,实际上还可以使用它

编辑 在字符串聚合中添加分隔符,因为{1,2,3}将生成与{1,23}相同的字符串

编辑2 重新添加我的第一种方法,确定列表B是否存在于列表A中,可能是分散的,但仍然是有序的:

var result = B.Intersect(A).SequenceEqual(B)

基本上,您希望在A上滑动并用B检查该窗口的每个元素。最后一部分实际上是SequenceEqual,我建议使用它,但这只是解释这一点的另一种选择:

bool equal = Enumerable.Range(0, A.Count() - B.Count() + 1)
    .Select(i => A.Skip(i).Take(B.Count))
    .Any(w => w.Select((item, i) => item.Equals(B[i])).All(item => item));

因此,这实际上是一个子字符串搜索。听起来,与其重新发明轮子,不如尝试实现。可以使用Enumerable.Intersect然后计算结果?-我们可以围绕这些类构建一个包装器,并为它们提供唯一的ID。类列表{List my_345List{get;set;}@spender虽然复制解决了我正在做的事情,但据我所知,你是对的,而且实现该算法会更有效,因为它避免了所有元素的循环,谢谢你的输入,我也会试试!@aspxsushil抱歉,我不知道这在哪一点上会有帮助?你不需要ToList、 由{1,2,3,4,6,3,5}和{3,4,5}的相交返回的IEnumerable上的SequenceEqual功将产生{3,4,5}.这不会产生正确的计算结果。@Adrian:我的错,我会删除ToList。此外,我发现我按错误的顺序相交,正在修复它too@Eliasar啊,对不起,我错过了他们不允许分散。这不检查订单
bool equal = Enumerable.Range(0, A.Count() - B.Count() + 1)
    .Select(i => A.Skip(i).Take(B.Count))
    .Any(w => w.Select((item, i) => item.Equals(B[i])).All(item => item));