代码之家  ›  专栏  ›  技术社区  ›  derHugo

如何检查一个列表<T>是否包含另一个列表<T>

  •  0
  • derHugo  · 技术社区  · 6 年前

    有什么优雅的方式进去吗 c# 检查 List<T> 包含子对象- 列表<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;
    }
    

    但我希望有更好的办法。

    0 回复  |  直到 6 年前
        1
  •  6
  •   Kristoffer Lerbæk Pedersen    6 年前

    var result = A.Select(a => $"{a}").Aggregate((c, n) => $"{c};{n}").Contains(B.Select(b => $"{b}").Aggregate((c, n) => $"{c};{n}"));
    

    喜欢 string.Contains 实际上,你可以用它。

    编辑

    编辑2

    var result = B.Intersect(A).SequenceEqual(B)
    
        2
  •  0
  •   Johnny    6 年前

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