简体   繁体   English

C#Linq将元素添加到满足条件的对象列表中

[英]C# Linq add element to list of object where condition is met

I have a player class 我有一个球员班

public class Player : Person
{
    public List<int> SetPoints;
}

And a game class 还有一个游戏课

private List<Player> Players;

public Game(List<Player> players)
{
    Players = players;
}

public void Simulate()
{
    var winnerPoints = 6;
    var looserPoints = Tournament.Random.Next(0, 5);
    var winnerId = Players[Tournament.Random.Next(0, 1)].Id;

    Players.Where(p => p.Id == winnerId).Select(p => p.SetPoints).Add(winnerPoints);
}

The code demonstrates what im trying to accomplish but i cant access the SetPoints list for updating, in the selected player object. 该代码演示了即时通讯试图完成的工作,但是我无法在选定的播放器对象中访问SetPoints列表进行更新。 Can anyone point out what modification i need to make in order for this to work? 谁能指出我需要进行哪些修改才能使其正常工作?

Thanks in advance 提前致谢

UPDATED 更新

My goal was to add winnerPoints to SetPoints of one random Player object in Players , and loserPoints to the other ( Players is always a list of two objects, provided by the constructor) thanks to maccettura i accomplished this by using FirstOrDefault() 我的目标是增加winnerPoints到一个随机的设置点Player在目标Players ,并loserPoints其他( Players通常是两个对象的列表,通过构造函数中提供)由于maccettura我使用做到了这一点FirstOrDefault()

    public void Simulate()
    {
        var winnerPoints = 6;
        var loserPoints = Tournament.Random.Next(0, 5);
        var winnerId = Players[Tournament.Random.Next(0, 1)].Id;

        Players.FirstOrDefault(p => p.Id == winnerId).SetPoints.Add(winnerPoints);
        Players.FirstOrDefault(p => p.Id != winnerId).SetPoints.Add(loserPoints);
    }

If you want a single matching Player object: 如果要单个匹配的Player对象:

The code you are using now does not do what you think it does: 您现在使用的代码无法执行您认为的操作:

Players.Where(p => p.Id == winnerId).Select(p => p.SetPoints)

What this is doing is looking for all matches on winnerId , then selecting all of the matching lists properties. 这是在查找winnerId上的所有匹配winnerId ,然后选择所有匹配列表属性。 This results in an IEnumerable<List<int>> . 这导致IEnumerable<List<int>>

If you need just one Player , to do that you need to use FirstOrDefault() : 如果只需要一个Player ,则需要使用FirstOrDefault()

var player = Players.FirstOrDefault(p => p.Id == winnerId);
//Check if player is not null, then add

This will give you a Player as the return, or the default(Player) (null) if there is no match. 这将为您提供一个Player作为回报,如果没有匹配项,则为default(Player) (空)。

Now that you have the Player object you can access the SetPoints property and Add() from there. 现在您有了Player对象,您可以从那里访问SetPoints属性和Add()了。

If you want all matching Player objects: 如果要所有匹配的Player对象:

If you want all matching Player objects you just need to iterate over your Where() query results: 如果想要所有匹配的Player对象,则只需要遍历Where()查询结果:

//Where() returns an IEnumerable<Player>
foreach(Player p in Players.Where(p => p.Id == winnerId))
{
    p.SetPoints.Add(winnerPoints);
}

Assuming that winnerId is unique, it would be sufficient to find a single result using FirstOrDefault : 假设winnerId是唯一的,那么使用FirstOrDefault查找单个结果就足够了:

Players.FirstOrDefault(p => p.Id == winnerId)?.SetPoints.Add(winnerPoints);

For the case (or rather, another use case) that it isn't unique, and you actually want a list of results, you could use ForEach() after a call to ToList() (or a standard foreach loop): 对于不是唯一的情况(或者另一个用例),并且您实际上想要一个结果列表,可以在调用ToList() (或标准的foreach循环)之后使用ForEach() ):

Players.Where(p => p.Id == winnerId).ToList().ForEach(p => p.SetPoints.Add(winnerPoints));

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

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