代码之家  ›  专栏  ›  技术社区  ›  Cristian Diaconescu

取列表中的第二个对象

  •  7
  • Cristian Diaconescu  · 技术社区  · 16 年前

    我有一个IEnumerable,我想得到一个包含每个第n个元素的新IEnumerable。

    这可以在LINQ中完成吗?

    3 回复  |  直到 16 年前
        1
  •  23
  •   Cristian Diaconescu    16 年前

    我自己解决了…

    这个 IEnumerable<T>.Where() 方法有一个重载,它获取当前元素的索引——这正是医生命令的内容。

    (new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0);
    

    这个会回来的

    {1, 3, 5}
    

    更新:为了涵盖我的用例和Dan Tao的建议,我们还要指定第一个返回元素应该是什么:

    var firstIdx = 1;
    var takeEvery = 2;
    var list =  new []{1,2,3,4,5};
    
    var newList = list
        .Skip(firstIdx)
        .Where((elem, idx) => idx % takeEvery == 0);
    

    ……会回来

    {2, 4}
    
        2
  •  8
  •   Community Mohan Dere    9 年前

    实施 Cristi's suggestion :

    public static IEnumerable<T> Sample<T>(this IEnumerable<T> source, int interval)
    {
        // null check, out of range check go here
    
        return source.Where((value, index) => (index + 1) % interval == 0);
    }
    

    用途:

    var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    var evens = upToTen.Sample(2);
    var multiplesOfThree = upToTen.Sample(3);
    
        3
  •  0
  •   Albin Sunnanbo    16 年前

    虽然不是Linq,但也可以使用 yield .

    public static IEnumerable<T> EverySecondObject<T>(this IEnumerable<T> list)
    {
        using (var enumerator = list.GetEnumerator())
        {
            while (true)
            {
                if (!enumerator.MoveNext())
                    yield break;
                if (enumerator.MoveNext())
                    yield return enumerator.Current;
                else
                    yield break;
            }
        }
    }