假设我有一个名为List<String>
的无序letters
:
letters.Add("d.pdf");
letters.Add("a.pdf");
letters.Add("c.pdf");
letters.Add("b.pdf");
letters.Add("e.pdf");
letters.Add("f.pdf");
我想按字母顺序排列该列表,然后在b
和d
(包括端点)之间获取元素,这样会返回一个新的列表,如{"b.pdf","c.pdf","d.pdf"}
。
答案 0 :(得分:2)
简单foreach
循环解决方案:
var letters = new List<string> {"d", "a", "c", "b", "e"};
letters.Sort();
var start = "b";
var end = "d";
var r = new List<string>();
foreach (var l in letters)
{
if (l.CompareTo(start) >= 0 && l.CompareTo(end) <= 0)
{
r.Add(l);
}
}
另一个简单的解决方案:
var letters = new List<string> {"d", "a", "c", "b", "e"};
letters.Sort();
var startIndex = letters.IndexOf(letters.Find(l=> l.CompareTo(start) == 0));
var endIndex = letters.IndexOf(letters.Find(l => l.CompareTo(end) == 0));
var r = letters.GetRange(startIndex, endIndex - startIndex + 1);
如果你使用TakeWhile
,这个解决方案应该可行,这更像是Linq。主要问题是在第一个集合索引中包含起始元素,否则TakeWhile
将无法工作。
var letters = new List<string> { "d", "a", "c", "b", "e" };
letters.Sort();
var start = "b";
var end = "d";
var startIndex = letters.IndexOf(letters.Find(l=> l.CompareTo(start) == 0));
var r = letters.GetRange(startIndex, letters.Count - startIndex)
.TakeWhile(l => l.CompareTo(start) >= 0 && l.CompareTo(end) <= 0).ToList();
答案 1 :(得分:0)
这适用于您的情况:
letters.OrderBy(x => x).TakeWhile(x => x != "e.pdf");
如果要概括它,可以编写扩展方法:
public static IEnumerable<TSource> GetRange<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> start,
Func<TSource, bool> end)
{
int counter = 0;
foreach (var item in source)
{
if (start(item) || end(item))
{
yield return item;
counter++;
if(counter == 2) yield break;
}else if (counter != 0) yield return item;
}
}
然后使用它:
letters.OrderBy(x => x).GetRange(x => x == "b.pdf", x => x == "d.pdf");
或者您可以在不使用LINQ
的情况下执行此操作,List<T>
也有GetRange
方法:
letters.Sort();
int startIndex = letters.IndexOf("b.pdf");
int endIndex = letters.IndexOf("d.pdf");
var result = letters.GetRange(startIndex, endIndex - startIndex +1);
答案 2 :(得分:0)
我不确定是否有内置功能可以轻松支持,但添加新的扩展方法后,您可以轻松实现:
void Main()
{
var letters = new List<string>();
letters.Add("d.pdf");
letters.Add("a.pdf");
letters.Add("c.pdf");
letters.Add("b.pdf");
letters.Add("e.pdf");
var results = letters
.OrderBy(x => x)
.SkipWhile(x => x != "b.pdf")
.TakeTo(x => x == "d.pdf")
.ToList();
}
static class Extensions
{
public static IEnumerable<TValue> TakeTo<TValue>(this IEnumerable<TValue> source, Func<TValue, bool> predicate)
{
bool predicateReached = false;
foreach (var value in source)
{
yield return value;
predicateReached = predicate(value);
if (predicateReached) yield break;
}
}
}
TakeTo
扩展方法的工作方式类似于TakeWhile
扩展名,但它会产生所有值,直到并包含与给定谓词函数匹配的第一个值。