数组的StartWith方法

Rom*_*omz 0 .net c# linq performance

.NET中的数组是否有StartWith方法?或者LINQ中的类似内容?

var arr1 = { "A", "B, "C" }
var arr2 = { "A", "B, "C", "D" } 

var arr3 = { "A", "B, "CD" } 
var arr4 = { "E", "A, "B", "C" } 

arr2.StartWith(arr1) // true
arr1.StartWith(arr2) // false

arr3.StartWith(arr1) // false
arr4.StartWith(arr1) // false
Run Code Online (Sandbox Code Playgroud)

或者我应该直截了当地说:

bool StartWith(string[] arr1, string[] arr2)
{
     if (arr1.Count() < arr2.Count) return false;

     for (var i = 0; i < arr2.Count(), i++)
     {
        if (arr2[i] != arr1[i]) return false;
     }

     return true;
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找最有效的方法.

Blo*_*ard 6

bool answer = arr2.Take(arr1.Length).SequenceEqual(arr1);
Run Code Online (Sandbox Code Playgroud)


Sco*_*ain 6

无论如何,你的"striaghtformward"方式是大多数LINQ方法的方式.你可以做一些调整.例如,将其作为扩展方法并使用比较器来比较两种类型,以便可以使用自定义比较器.

public static class ExtensionMethods
{
    static bool StartWith<T>(this T[] arr1, T[] arr2)
    {
        return StartWith(arr1, arr2, EqualityComparer<T>.Default);
    }

    static bool StartWith<T>(this T[] arr1, T[] arr2, IEqualityComparer<T> comparer)
    {
         if (arr1.Length < arr2.Length) return false;

         for (var i = 0; i < arr2.Length, i++)
         {
            if (!comparer.Equals(arr2[i], arr1[i])) return false;
         }

         return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:为了好玩,我决定花时间编写一个更高级的"高级"版本,它可以用于任何IEnumerable<T>而不仅仅是数组.

public static class ExtensionMethods
{
    static bool StartsWith<T>(this IEnumerable<T> @this, IEnumerable<T> @startsWith)
    {
        return StartsWith(@this, startsWith, EqualityComparer<T>.Default);
    }

    static bool StartsWith<T>(this IEnumerable<T> @this, IEnumerable<T> startsWith, IEqualityComparer<T> comparer)
    {
        if (@this == null) throw new ArgumentNullException("this");
        if (startsWith == null) throw new ArgumentNullException("startsWith");
        if (comparer == null) throw new ArgumentNullException("comparer");

        //Check to see if both types implement ICollection<T> to get a free Count check.
        var thisCollection = @this as ICollection<T>;
        var startsWithCollection = startsWith as ICollection<T>;
        if (thisCollection != null && startsWithCollection != null && (thisCollection.Count < startsWithCollection.Count)) 
            return false;

        using (var thisEnumerator = @this.GetEnumerator())
        using (var startsWithEnumerator = startsWith.GetEnumerator())
        {
            //Keep looping till the startsWithEnumerator runs out of items.
            while (startsWithEnumerator.MoveNext())
            {
                //Check to see if the thisEnumerator ran out of items.
                if (!thisEnumerator.MoveNext())
                    return false;

                if (!comparer.Equals(thisEnumerator.Current, startsWithEnumerator.Current))
                    return false;

            }
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)


Hab*_*bib 5

你可以做:

var result = arr2.Take(arr1.Length).SequenceEqual(arr1);
Run Code Online (Sandbox Code Playgroud)

要进一步优化它,您可以arr2.Length >= arr1.Length在开头添加检查 ,如:

var result = arr2.Length >= arr1.Length && arr2.Take(arr1.Length).SequenceEqual(arr1);
Run Code Online (Sandbox Code Playgroud)

最终结果是一样的.