[英]extending ienumerable method C#
我寫了跳過最后一個方法。 當我用int數組調用它時,我希望只返回2個元素,而不是4個。
怎么了?
謝謝
public static class myclass
{
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int n)
{
return source.Reverse().Skip(n).Reverse();
}
}
class Program
{
static void Main(string[] args)
{
int [] a = new int[] {5, 6, 7, 8};
ArrayList a1 = new ArrayList();
a.SkipLast(2);
for( int i = 0; i <a.Length; i++)
{
Console.Write(a[i]);
}
}
}
您需要致電為
var newlist = a.SkipLast(2);
for( int i = 0; i <newlist.Count; i++)
{
Console.Write(newlist[i]);
}
您的方法返回跳過列表,但原始列表不會更新
如果您要分配或更新相同的列表,則可以將返回的列表設置為a = a.SkipLast(2).ToArray();
您應該分配結果 ,而不僅僅是a.SkipLast(2)
:
a = a.SkipLast(2).ToArray(); // <- if you want to change "a" and loop on a
for( int i = 0; i <a.Length; i++) { ...
當您執行a.SkipLast(2)
它將創建IEnumerable<int>
,然后將其丟棄 ; 最易讀的解決方案,恕我直言,是使用foreach ,這對於LINQ非常方便:
...
int [] a = new int[] {5, 6, 7, 8};
foreach(int item in a.SkipLast(2))
Console.Write(item);
將您的代碼更改為
foreach (var r in a.SkipLast(2))
{
Console.Write(r);
}
出於三個原因,
SkipLast
函數返回突變的序列,它不會直接對其進行更改。 IEnumerable
中使用索引器有什么意義? 它強加了不必要的計數。 有關更有效的通用SkipLast
請參閱帶有枚舉器的Matthew緩沖區。
您的示例可以使用更專業的SkipLast
,
public static IEnumerable<T> SkipLast<T>(this IList<T> source, int n = 1)
{
for (var i = 0; i < (source.Count - n); i++)
{
yield return source[i];
}
}
其他答復已經回答了您的問題,但是這樣做不是更有效的實現(它不涉及制作數組的兩個副本以將其反轉兩次)。 它將迭代兩次(或一次,然后進行count-n次訪問):
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int n)
{
n = source.Count() - n;
return source.TakeWhile(_ => n-- > 0);
}
實際上,如果source
是無需迭代即可實現Count
的類型(例如數組或List),則它將僅訪問count-n
次元素,因此對於這些類型而言,這將非常高效。
這是一個更好的解決方案,它只將序列重復一次。 數據要求如此,它只需要一個包含n
元素的緩沖區,如果n
與序列的大小相比很小,這將非常有效:
public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int n)
{
int count = 0;
T[] buffer = new T[n];
var iter = source.GetEnumerator();
while (iter.MoveNext())
{
if (count >= n)
yield return buffer[count%n];
buffer[count++%n] = iter.Current;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.