[英]Get n items from list of list using linq
我有一个包含其他用户/播放器列表的列表。 这些用户按照他们的特定范围的高尔夫障碍进行分组和分类。 例如,内部列表包含的索引
[0] =>计数2(玩家)
1 =>计数3(玩家)
[2] =>计数1(玩家)
为了在锦标赛中进行飞行,这些玩家/用户被分组为每次飞行最多3或4个玩家。 我如何根据指定的限额填写每个航班。 零索引包含2个玩家,因此我必须从下一个索引中减去其余2个玩家,依此类推以补偿玩家。
对于上述所有情况,我试图使用LINQ查询执行此类功能,但无法解决。 下面是我尝试过的。
List<List<Models.User>> PlayerSortedList = new List<List<Models.User>>(); //contains all the grouped players
foreach (var item in PlayerSortedList)
{
var extraPlayers = new List<Models.User>();
if (item.Count != Convert.ToInt16(vm.flight.PlayerLimit))
{
//Take extra players from next list and remove players from the next list
int limit = Convert.ToInt16(vm.flight.PlayerLimit) - item.Count;
var players = PlayerSortedList.Skip(i); // this has not skipped the first index
extraPlayers = (from player in players
from p in player
where player.Count > 0
orderby (p.UserHandicap).Take(limit)
select p).ToList(); // generating error as must be icomparable but i dont
have to compare anything, but take out players from the next items in the list
}
通过从列表中的下一个项目中抽出额外的玩家,我确实必须将它们添加到上一个列表中,并从我已删除的列表中删除那些玩家。
那这个呢?
static void Main(string[] args)
{
var listOfListOfPlayers = new List<List<Player>>();
//Flatten the list, so not having to deal with lists of lists
var allPlayers = listOfListOfPlayers.SelectMany(l => l).ToList();
//Count the players that can not take part of a flight
var playersNotFittingInFlight = allPlayers.Count % 4;
//The number of players that will be spread in flights
var maxPlayersInFlights = allPlayers.Count - playersNotFittingInFlight;
//The number of flights you will end up having
var maxFlights = maxPlayersInFlights / 4;
var flights = new List<Flight>(maxFlights);
//Create the flights with the players
for (var i=0;i<maxPlayersInFlights; i=i+4)
{
var flight = new Flight();
//Take 4 players everytime.
var players = allPlayers.Skip(i).Take(4);
flight.Players.AddRange(players);
flights.Add(flight);
}
}
public class Flight
{
public List<Player> Players { get; set; } = new List<Player>();
}
public class Player
{
}
}
可以通过使用单个linq查询来做到这一点。
var limit = 4;
var results = playerSortedList
// Combine all the users in the lists into a single list
.SelectMany(l => l)
// .SelectMany(l => l.OrderBy(x=>x.Handicap)) // use this in case it is needed to reorder the users within each sub list.
// Use index of the users within the list to create bucket numbers.
.Select((user, idx) => new { User = user, Bucket = (idx / limit) })
// Group the users using the bucket numbers.
.GroupBy(x => x.Bucket)
// Make the whole thing a List<List<User>> again.
.Select(x=>x.Select(bucket => bucket.User).ToList())
.ToList();
亲切的问候,D.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.