有没有办法在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
是的,我可以编写自己的方法,但这不是我要求的。我将接受嵌套查询。
答案 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);