Linq 以不同方式处理第一个IEnumerable项的最优雅方式
在不必在每次迭代中进行测试的情况下,以不同于其他方式处理第一个IEnumerable项的最优雅方式是什么 在每次迭代中进行一次测试,结果如下所示:Linq 以不同方式处理第一个IEnumerable项的最优雅方式,linq,ienumerable,skip,Linq,Ienumerable,Skip,在不必在每次迭代中进行测试的情况下,以不同于其他方式处理第一个IEnumerable项的最优雅方式是什么 在每次迭代中进行一次测试,结果如下所示: // "first item done" flag bool firstDone = false; // items is an IEnumerable<something> foreach (var item in items) { if (!firstDone) { // do this only o
// "first item done" flag
bool firstDone = false;
// items is an IEnumerable<something>
foreach (var item in items)
{
if (!firstDone)
{
// do this only once
ProcessDifferently(item);
firstDone = true;
continue;
}
ProcessNormally(item);
}
它将调用两次GetEnumerator
,我希望避免这种情况(例如,对于Linq到Sql的情况)
如果需要对代码执行多次操作,您将如何执行此操作?如果需要在多个位置执行此操作,我将提取一个方法:
public void Process<T>(IEnumerable<T> source,
Action<T> firstAction,
Action<T> remainderAction)
{
// TODO: Argument validation
using (var iterator = source.GetEnumerator())
{
if (iterator.MoveNext())
{
firstAction(iterator.Current);
}
while (iterator.MoveNext())
{
remainderAction(iterator.Current);
}
}
}
还有其他选择,但这取决于具体情况。你可以用老式的方式:
var itemsList = items.ToList();
ProcessDifferently(itemsList[0]);
for(int i=1;i<itemsList.Count;i++)
{
ProcessNormally(itemsList[i]);
}
var itemsList=items.ToList();
处理方式不同(itemsList[0]);
对于(inti=1;i,还有另一种方法:
private static void Main(string[] args)
{
var testdata = new[] { "a", "b", "c", "d", "e" };
var action = FirstThenRest<string>(
s => Console.WriteLine("First: " + s),
s => Console.WriteLine("Rest: " + s));
foreach (var s in testdata)
action(s);
}
public static Action<T> FirstThenRest<T>(Action<T> first, Action<T> rest)
{
Action<T> closure = t =>
{
first(t);
closure = rest;
};
return t => closure(t);
}
没有条件。:D
编辑:“头”和“尾”可能是更好的术语,但我现在懒得去更改它。谢谢,干净整洁。完全符合我的要求。这将适用于列表和数组,但我需要对IEnumerable执行相同的操作,而不需要重复两次。啊,是的,你是对的。为了清晰起见,我修改了代码示例。使用skeets答案-非常好。
var itemsList = items.ToList();
ProcessDifferently(itemsList[0]);
for(int i=1;i<itemsList.Count;i++)
{
ProcessNormally(itemsList[i]);
}
private static void Main(string[] args)
{
var testdata = new[] { "a", "b", "c", "d", "e" };
var action = FirstThenRest<string>(
s => Console.WriteLine("First: " + s),
s => Console.WriteLine("Rest: " + s));
foreach (var s in testdata)
action(s);
}
public static Action<T> FirstThenRest<T>(Action<T> first, Action<T> rest)
{
Action<T> closure = t =>
{
first(t);
closure = rest;
};
return t => closure(t);
}
First: a
Rest: b
Rest: c
Rest: d
Rest: e