我最近遇到了一个场景,我需要检查一个IEnumerable<T>
是否以一些IEnumerable<T>
前缀开头。我搜索并没有找到一个现有的StackOverflow答案,所以我决定在下面的答案中提供我自己的解决方案。如何在.NET中检查IEnumerable <T>是否以另一个IEnumerable <T>开头?
2
A
回答
1
这是一种LINQ风格的扩展方法,我通过允许您传入自定义相等比较器来灵活地实现我的实现:例如,如果您希望new[] { "SOME", "IMPORTANT", "WORDS" }.StartsWith(new[] { "some", "important" })
为真,则可以在prefix
参数后面添加StringComparer.OrdinalIgnoreCase
。
public static bool StartsWith<T>(this IEnumerable<T> source, IEnumerable<T> prefix, IEqualityComparer<T> comparer = null)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (prefix == null)
{
throw new ArgumentNullException(nameof(prefix));
}
comparer = comparer ?? EqualityComparer<T>.Default;
using (var sourceEnumerator = source.GetEnumerator())
using (var prefixEnumerator = prefix.GetEnumerator())
{
while (true)
{
if (!sourceEnumerator.MoveNext())
{
return !prefixEnumerator.MoveNext();
}
if (!prefixEnumerator.MoveNext())
{
return true;
}
if (!comparer.Equals(sourceEnumerator.Current, prefixEnumerator.Current))
{
return false;
}
}
}
}
6
你的扩展是好的,但你可以使用已有的Enumerable.Zip
+ All
:
var longerSeq = new[] { "SOME", "IMPORTANT", "WORDS" };
var shorterSeq = new[] { "some", "important" };
bool startsWithCaseInsensitive = longerSeq
.Zip(shorterSeq, (l, s) => string.Equals(l, s, StringComparison.OrdinalIgnoreCase))
.All(b => b); // are all bools true? Returns false on first false
的方法合并第一序列的每个元素与元素 在第二个序列中具有相同的索引。 如果序列不 没有相同数量的元素,方法合并序列 直到它到达其中一个结束
由于Zip
使用延迟执行它不会评估所有,如果第一已产生了false
。
+1
虽然这不等同于OP解决方案。如果“前缀”序列长于“源”序列,'StartsWith'应该返回'false'。哪个'Zip'实现无法区分。 –
0
bool result = longerList.Take(shorterList.Count).SequenceEqual(shorterList);
你也可以添加比较方法SequenceEqual:
bool result = longerList.Take(shorterList.Count).SequenceEqual(shorterList, new MyComparer<string>);
相关问题
- 1. LINQ:从另一个IEnumerable <T>创建IEnumerable <T>?
- 2. 如何从IEnumerable <T1>中检索IEnumerable <T2>?
- 3. 将IEnumerable <T>与IEnumerable比较IEnumerable <IEnumerable <T>>
- 4. 如何循环访问IEnumerable <string>并创建另一个IEnumerable <string>?
- 5. 如何检查IEnumerable <T>是否是IInterface?
- 6. 如何将IEnumerable <IEnumerable <IGrouping <int,string> >>转换为IEnumerable <IEnumerable <string>>
- 7. 如何将IEnumerable <IEnumerable <Foo>>减少到IEnumerable <Foo>?
- 8. 如何将IEnumerable <IEnumerable <T>>转换为IEnumerable <T>
- 9. 检查一个IEnumerable是否包含另一个IEnumerable的所有元素
- 10. .NET反思:检测的IEnumerable <T>
- 11. 铸造IEnumerable <Derived> IEnumerable <BaseClass>
- 12. 从IEnumerable <IEnumerable <T>>
- 13. 分组IEnumerable <IEnumerable <int>>
- 14. IEnumerable <IEnumerable <T>> to string [] []
- 15. 产量返回IEnumerable <IEnumerable <...>>
- 16. “转动”一个IEnumerable <IEnumerable <T>> 90度
- 17. 如何连接两个IEnumerable <T>到一个新的IEnumerable <T>?
- 18. 如何检查IEnumerable是否是List?
- 19. .NET检查两个IEnumerable的<T>有相同的元素
- 20. 如何检查一个元素是否在IEnumerable中重复?
- 21. 我如何拆分一个IEnumerable <String>到IEnumerable的组<string>
- 22. 是否可以写一个递归的IEnumerable <T>
- 23. 如何将List <IEnumerable <ProductViewModel >>转换为<IEnumerable <ProductViewModel >>?
- 24. 如何将`IEnumerable <Unknown T>`转换为`IEnumerable <Whatever>`
- 25. 如何从IEnumerable <MyClass>告诉IEnumerable <int>?
- 26. 如何将managementobject集合转换为IEnumerable <IEnumerable <IPropertyData >>?
- 27. 如何从列表<IEnumerable <ItemClass>>中选择IEnumerable <ItemClass>?
- 28. 转换一个IEnumerable <组<TParent,年掳>>到IEnumerable <TParent>
- 29. 检查的IEnumerable <T>与反思
- 30. 何时使用IEnumerable over IEnumerable <>
请不要使用StackOverflow的您的个人博客。提出一个问题,但不要像这样一次提出问题并回答问题。 – Enigmativity
@Enigmativity我不认为回答我自己的问题有什么问题。这是我遇到的一个真正的问题,其他人也可能遇到。我将与世界其他地方分享我的知识,以便其他开发人员可以快速Google并找到解决方案,而不是浪费时间编写自己的实现。 –
我记得当时看到它被人折磨的地方,但我现在找不到那个参考。那么快乐的日子。去吧。 – Enigmativity