如何检查一个List <t>是否包含另一个List <t>

时间:2019-02-13 18:21:12

标签: c# .net

c#中是否有任何优雅的方法来检查List<T>是否包含类似于List<T>的子string.Contains(string)

比如说我想测试例如列表A中是否包含列表B

List<int> A = new List<int>{ 1, 2, 3, 4, 3, 4, 5 };
List<int> B = new List<int>{ 3, 4, 5 };

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


我知道我可以做类似的事情

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;
}

但我希望有更好的方法。

2 个答案:

答案 0 :(得分:6)

这里是一个班轮:

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)

答案 1 :(得分:0)

基本上,您想滑过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));