Check if one list contains all items from another list in order

后端 未结 4 1171
眼角桃花
眼角桃花 2020-12-16 06:51

How can I determine if List A contains all of the elements from List B in the same order?

List A can have additional elements that List B does not have, but must co

相关标签:
4条回答
  • 2020-12-16 07:07

    Use String.Join() to concat ListA elements together. Then use it again to concat ListB elements together. Then use ConcatListA.IndexOf(ConcatListB).

    0 讨论(0)
  • 2020-12-16 07:15

    I think my version is more efficient.

    public static class CollectionExtension
    {
        public static bool SequenceContain<T>(this IEnumerable<T> target, IEnumerable<T> that)
        {
            var targetEnumerater = target.GetEnumerator();
            var thatEnumerater = that.GetEnumerator();
            var thatHasValue = thatEnumerater.MoveNext();
            var targetHasValue = targetEnumerater.MoveNext();
            var matchCount = 0;
            try
            {
                while (thatHasValue && targetHasValue)
                {
                    if (!EqualityComparer<T>.Default.Equals(targetEnumerater.Current, thatEnumerater.Current))
                    {
                        if (matchCount > 0)
                        {
                            thatEnumerater.Reset();
                            thatEnumerater.MoveNext();
                            matchCount = 0;
                        }
                        targetHasValue = targetEnumerater.MoveNext();
                        continue;
                    }
                    targetHasValue = targetEnumerater.MoveNext();
                    thatHasValue = thatEnumerater.MoveNext();
                    matchCount++;
                }
                return matchCount == that.Count();
            }
            finally
            {
                thatEnumerater.Dispose();
                targetEnumerater.Dispose();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-16 07:22

    This takes each part of ListA and compares it with ListB with SequenceEqual:

    bool containsSameSequence = ListA
        .Where((item, index) => index <= ListA.Count - ListB.Count)
        .Select((item, index) => ListA.Skip(index).Take(ListB.Count))
        .Any(part => part.SequenceEqual(ListB));
    

    Demo

    It returns true on the first matching sequence.

    0 讨论(0)
  • 2020-12-16 07:30

    Here's a quick way:

    var equal = listA.Count - listB.Count < 0 
        ? false 
        : Enumerable.Range(0, listA.Count - listB.Count).Any(i => 
          listA.Skip(i).Take(listB.Count).SequenceEqual(listB));
    

    However, I'd prefer to use an extension method like this:

    public static bool ContainsSequence<T>(this IEnumerable<T> outer, 
                                           IEnumerable<T> inner)
    {
        var innerCount = inner.Count();
        for(int i = 0; i < outer.Count() - innerCount; i++)
        {
            if(outer.Skip(i).Take(innerCount).SequenceEqual(inner))
                return true;
        }
    
        return false;
     }
    

    which you can call like:

    var equals = listA.ContainsSequence(listB);
    

    And here's a more efficient version of the same extension method specific to List<T>:

    public static bool ContainsSequence<T>(this List<T> outer, List<T> inner)
    {
        var innerCount = inner.Count;
    
        for (int i = 0; i < outer.Count - innerCount; i++)
        {
            bool isMatch = true;
            for (int x = 0; x < innerCount; x++)
            {
                if (!outer[i + x].Equals(inner[x]))
                {
                    isMatch = false;
                    break;
                }
            }
    
            if (isMatch) return true;
        }
    
        return false;
    }
    
    0 讨论(0)
提交回复
热议问题