C# 使用LINQ快速比较阵列的方法
有没有一种方法可以在LINQ中编写短代码来检查一个数组是否是另一个数组的子序列并遵守一个命令 例如,伪代码:C# 使用LINQ快速比较阵列的方法,c#,arrays,linq,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 dou
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
编辑:
编辑2:
例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
是的,我可以写我自己的方法,但这不是我想要的。我将接受嵌套查询。您可以编写自己的方法来执行此操作。我将此方法作为扩展方法:
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;
}
}
下面是相同的另一个实现:
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;
}
}
是的。基于Nacho的,这是我的解决方案,并不理想,但我现在就接受它:
[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);
你可以自己写function@YuriyFaktorovich这不是重复的,因为OP需要相同顺序的子集。@maccettura很显然,他们在得到答案之前就已经知道如何做了。他们只是不想。
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
[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);