繁体   English   中英

如何在LINQ查询中返回项目的相邻项目

[英]How to return neighbouring items of an item in a LINQ query

考虑以下集合

var players = new[]{
     new {Id = 1, Name = "A", Score = 70},
     new {Id = 2, Name = "B", Score = 50},
     new {Id = 3, Name = "C", Score = 100},
     new {Id = 4, Name = "D", Score = 90}
 };

如果我想按分数排序返回上面列表中特定玩家(例如,ID = 1的玩家)的位置,我可以编写如下查询:

var result = players.OrderByDescending(p => p.Score)
             .Select((p, i) => new {player = p, Position = i})
             .Where(x => x.player.Id == 1)
             .First();
int position = result.Position;
var player = result.player;

现在,我该如何进一步处理并退还除实际玩家以外的其他物品 当我们按分数排序列表时,相邻的项目是上一个和下一个玩家以及它们各自的位置。

这是查询的预期结果

var expectedResult = new[]{
    new {Id = 2, Name = "B", Score = 50},   //Previous player
    new {Id = 1, Name = "A", Score = 70},
    new {Id = 4, Name = "D", Score = 90}    //Next Player 
};

是否可以通过单个LINQ表达式来获得上述结果? 任何帮助,将不胜感激。

您可以使用.NET 4.0中定义的Zip运算符,也可以使用Rx扩展中定义的Scan运算符:

带拉链:

var result = players.OrderByDescending(p => p.Score)
    .Select((p, i) => new {Player = p, Position = i})
    .ToList(); //forces evaluation

result.Zip(result.Skip(1), (i,j) => new {First= i, Second=j})
      .Zip(result.Skip(2), (i,j) => new {First = i.First, Second = i.Second, Third=j})
      .First(o => o.Second.player.Id == 1);

但是,这不会给您第一个和最后一个玩家的邻居。 如果您也想要它们,则必须对您的收藏进行按摩(因为所有三个同等数量的物品必须具有相同的数量)

我会这样写:

public static IEnumerable<IList<T>> GetOverlappingChunks<T>(
    this IEnumerable<T> sequence, int chunkSize)
{
    List<T> chunk = new List<T>(chunkSize);

    foreach (var elt in sequence)
    {
        chunk.Add(elt);

        if (chunk.Count > chunkSize)
            chunk.RemoveAt(0);

        if (chunk.Count == chunkSize)
            yield return chunk.ToArray();
    }
}

// ...

var result = players.OrderByDescending(p => p.Score)
             .GetOverlappingChunks(3)
             .Where(x => x[1].Id == 1);

(太糟糕的C#没有内置的双端队列类型。)

如果需要处理列表中少于三个玩家的情况,则需要微调GetOverlappingChunks和检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM