web-dev-qa-db-ja.com

LINQを使用してリストから指定されたインデックス範囲内の値を選択する方法

私はそれを使って次のことを達成しようとするLINQ初心者です。

私はintのリストを持っています:-

List<int> intList = new List<int>(new int[]{1,2,3,3,2,1});

ここで、LINQを使用して、最初の3つの要素の合計[インデックス範囲0〜2]と最後の3つの要素[インデックス範囲3〜5]を比較します。 LINQ SelectおよびTake拡張メソッドとSelectManyメソッドを試しましたが、次のような言い方を理解できません

(from p in intList  
where p in  Take contiguous elements of intList from index x to x+n  
select p).sum()

Contains拡張メソッドも見てみましたが、それは私が欲しいものを取得するために表示されません。助言がありますか?ありがとう。

60
Punit Vora

Skip を使用してからTakeを使用します。

yourEnumerable.Skip(4).Take(3).Select( x=>x )

(from p in intList.Skip(x).Take(n) select p).sum()
88
Adam Sills

GetRange()を使用できます

list.GetRange(index, count);
35
Onuralp

リストが大きい場合は、パフォーマンスのために別の拡張方法が適している可能性があります。私はこれが最初の場合には必要ではないことを知っていますが、Linq(オブジェクトへの)実装はリストの反復に依存しているため、大きなリストの場合、これは(無意味に)高価になります。これを実現する簡単な拡張方法は次のとおりです。

public static IEnumerable<TSource> IndexRange<TSource>(
    this IList<TSource> source,
    int fromIndex, 
    int toIndex)
{
    int currIndex = fromIndex;
    while (currIndex <= toIndex)
    {
        yield return source[currIndex];
        currIndex++;
    }
}
17
Tao

特定のインデックス(from-toではない)でフィルタリングするには:

public static class ListExtensions
{
   public static IEnumerable<TSource> ByIndexes<TSource>(this IList<TSource> source, params int[] indexes)
   {        
        if (indexes == null || indexes.Length == 0)
        {
            foreach (var item in source)
            {
                yield return item;
            }
        }
        else
        {
            foreach (var i in indexes)
            {
                if (i >= 0 && i < source.Count)
                    yield return source[i];
            }
        }
   }
}

例えば:

string[] list = {"a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9"};
var filtered = list.ByIndexes(5, 8, 100, 3, 2); // = {"f6", "i9", "d4", "c3"};
0
stomy