快速方法将数组与LINQ进行比较

时间:2018-02-06 17:41:44

标签: c# arrays linq

有没有办法在LINQ中编写短代码来检查一个数组是否是其他数组的子序列并遵守命令?

例如(伪代码):

var masterList = new double[] {0,1,2,3,4};
var lst1 = new double[] {0,1,2,3};
var lst2 = new double[] {0,1,3,4};
var lst3 = new double[] {2,3,4};
var lst4 = new double[] {3,4};
var lst5 = new double[] {4,3};

bool isSubseq1 = lst1.Compare(masterList); // true
bool isSubseq2 = lst2.Compare(masterList); // false
bool isSubseq3 = lst3.Compare(masterList); // true
bool isSubseq4 = lst4.Compare(masterList); // true
bool isSubseq5 = lst5.Compare(masterList); // false

编辑:

bool isSubseq = !lst5.Except(masterList).Any(); // returns true, but I want to return false

EDIT2: 例2:

var masterList = new double[] {0,1,2,3,4,4,4,5,6,6,8,8};
var lst1 = new double[] {0,1,2,3};
var lst2 = new double[] {0,3,4};
var lst3 = new double[] {4,4,4};
var lst4 = new double[] {6,6,8,8};
var lst5 = new double[] {5,4,4,4,3};
var lst6 = new double[] {9,9};

bool isSubseq1 = lst1.Compare(masterList); // true
bool isSubseq2 = lst2.Compare(masterList); // false
bool isSubseq3 = lst3.Compare(masterList); // true
bool isSubseq4 = lst4.Compare(masterList); // true
bool isSubseq5 = lst5.Compare(masterList); // false
bool isSubseq6 = lst6.Compare(masterList); // false

是的,我可以编写自己的方法,但这不是我要求的。我将接受嵌套查询。

3 个答案:

答案 0 :(得分:1)

您可以编写自己的方法来执行此操作。我把它变成了一个扩展方法:

$ sudo service cloudera-scm-server start

您可以这样使用它:

public static class Extensions
{
    public static bool IsSubsequencetOf<T>(this T[] subset, T[] items)
    {
        if (subset.Length < 1)
            return true;
        if (items.Length < 1)
            return false;

        for (int itemsIndex = 0; itemsIndex <= items.Length - subset.Length; ++itemsIndex)
        {
            if (items[itemsIndex].Equals(subset[0])) // Found a potential start of the subset
            {
                bool isMatch = true;
                int itemsIndexInner = itemsIndex + 1;
                for (int subsetIndex = 1; itemsIndexInner < items.Length && subsetIndex < subset.Length; ++subsetIndex)
                {
                    if (!items[itemsIndexInner].Equals(subset[subsetIndex]))
                    {
                        isMatch = false;
                        break;
                    }

                    itemsIndexInner++;
                }

                if (isMatch)
                    return true;
            }
        }

        return false;
    }
}

答案 1 :(得分:1)

这是另一个相同的实现:

public static class LinqEx
{
    public static bool IsSubsequenceOf<T>(
        this IEnumerable<T> subSequence, 
        IEnumerable<T> sequence) where T : IEquatable<T>
    {
        var subSequenceIterator = subSequence.GetEnumerator();
        if (!subSequenceIterator.MoveNext()) return true;
        var started = false;
        foreach (var superitem in sequence)
        {
            if (superitem.Equals(subSequenceIterator.Current))
            {
                started = true;
                if (!subSequenceIterator.MoveNext()) return true;
            }
            else if (started)
            {
                return false;
            }
        }
        return false;
    }
}

...超过您的数据:

bool isSubset1 = lst1.IsSubsequenceOf(masterList); // true
bool isSubset2 = lst2.IsSubsequenceOf(masterList); // false
bool isSubset3 = lst3.IsSubsequenceOf(masterList); // true
bool isSubset4 = lst4.IsSubsequenceOf(masterList); // true
bool isSubset5 = lst5.IsSubsequenceOf(masterList); // false

耶。

答案 2 :(得分:0)

基于Nacho的idea,这是我的解决方案(不理想,但我现在就接受):

    [TestCase(new int[] { 0, 1, 2, 3 }, true)]
    [TestCase(new int[] { 0, 3, 4 }, false)]
    [TestCase(new int[] { 4, 4, 4 }, true)]
    [TestCase(new int[] { 6, 6, 8, 8 }, true)]
    [TestCase(new int[] { 5, 4, 4, 4, 3 }, false)]
    [TestCase(new int[] { 9, 9 }, false)]
    [TestCase(new int[] { 0, 2 }, false)]
    [TestCase(new int[] { }, false)] // bug: SkipWhile skips all master's items, so master[] { } == sub[] { } is true;
    public void MethodToTest(int[] sub, bool expected)
    {
        var master = new int[] { 0, 1, 2, 3, 4, 4, 4, 5, 6, 6, 8, 8 };

        var result = master.SkipWhile((x, i) => !master.Skip(i).Take(sub.Length).SequenceEqual(sub))
            .Take(sub.Length).SequenceEqual(sub);

        Assert.AreEqual(expected, result);
    }

编辑:修复空数组问题:

    var result = master.SkipWhile((x, i) => !master.Skip(i).Take(sub.Length).SequenceEqual(sub))
        .Take(sub.Length).DefaultIfEmpty().SequenceEqual(sub);