类对象列表 - 使用LINQ过滤具有相同值的类对象

时间:2015-03-02 09:21:51

标签: linq list

我正在使用类对象(clsDetails)来存储播放器详细信息,如下所示。我试图使用LINQ过滤具有相同值的Class对象列表。

我想获得在所有5次尝试中成功的玩家列表。我正在尝试使用LINQ,但它不会返回正确的播放器。

class Program
    {
        static void Main(string[] args)
        {
            List<clsDetails> lstAllDetails = new List<clsDetails>();
            try
            {
                clsDetails cd;

            //Player 1
            cd = new clsDetails() { iAttemptId =1, sPlayerId="P1",sPlayerSuccess="YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P1", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P1", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P1", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P1", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);


            //Player 2
            cd = new clsDetails() { iAttemptId = 1, sPlayerId = "P2", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P2", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P2", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P2", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P2", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);

            //Player 3
            cd = new clsDetails() { iAttemptId = 1, sPlayerId = "P3", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P3", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P3", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P3", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P3", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);

            //Player 4
            cd = new clsDetails() { iAttemptId = 1, sPlayerId = "P4", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P4", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P4", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P4", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P4", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);

            //Player 5
            cd = new clsDetails() { iAttemptId = 1, sPlayerId = "P5", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P5", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P5", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P5", sPlayerSuccess = "NO" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P5", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);

            //Player 6
            cd = new clsDetails() { iAttemptId = 1, sPlayerId = "P6", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 2, sPlayerId = "P6", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 3, sPlayerId = "P6", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 4, sPlayerId = "P6", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);
            cd = new clsDetails() { iAttemptId = 5, sPlayerId = "P6", sPlayerSuccess = "YES" };
            lstAllDetails.Add(cd);

            //players successfull in first attempt itself
            var vSuccessFirstAttempt = (from d in lstAllDetails
                                        where d.sPlayerSuccess.ToUpper() == "YES" && d.iAttemptId == 1
                                        select d.sPlayerId);

            //Players successfull in all the 5 attempts
            var vSuccessAllAttempts = (from d in lstAllDetails
                                       group d by new {d.sPlayerId,d.sPlayerSuccess} into grp
                                        where grp.Count() ==1 && grp.Key.sPlayerSuccess =="YES"
                                        select grp.Key.sPlayerId);

            // vSuccessAllAttempts - Enumeration yielded No result

        }
        catch (Exception ex)
        { 

        }
    }

}

public class clsDetails
{
    public int iAttemptId = 0;
    public string sPlayerId = string.Empty;
    public string sPlayerSuccess = string.Empty;
}

我也想得到

  1. 第一次尝试成功的球员名单

  2. 第一次或第二次尝试成功的玩家名单

  3. 至少3次尝试成功的球员名单。

  4. 在所有5次尝试中成功的球员名单

  5. 我不确定以下查询的问题是什么,以及为什么它不会返回任何值。

    var vSuccessAllAttempts = (from d in lstAllDetails
                                               group d by new {d.sPlayerId,d.sPlayerSuccess} into grp
                                                where grp.Count() ==1 && grp.Key.sPlayerSuccess =="YES"
                                                select grp.Key.sPlayerId);
    

    由于 阿肖克

3 个答案:

答案 0 :(得分:2)

您需要定义两种方法:

private IEnumerable<string> GetPlayersSuccessfullInAttempt(IEnumerable<clsDetails> players, int attempt)
{
    return players.Where(p=>p.sPlayerSuccess = "YES" && p.iAttemptId == attempt)
        .Select(p => p.sPlayerId);
}

private IEnumerable<string> GetPlayersSuccessfullInAllAttempts(IEnumerable<clsDetails> players, int numberOfAttempts)
{
    return players.GroupBy(p => p.sPlayerId)
        .Where(g => g.Count(p => p.sPlayerSuccess >= "YES") == numberOfAttempts)
        .Select(g => g.Key); //g.Key is the player Id
}

现在,要获得结果:

var playersSuccessfullInFirstAttempt = GetPlayersSuccessfullInAttempt(lstAllDetails, 1);
var playersSuccessfullInFirstOrSecondAttempt = playersSuccessfullInFirstAttempt
    .Union(GetPlayersSuccessfullInAttempt(lstAllDetails, 2))
    .Distinct();

var successfullInAtLeast3 = GetPlayersSuccessfullInAllAttempts(lstAllDetails, 3);
var successfullInAll5 = GetPlayersSuccessfullInAllAttempts(lstAllDetails, 5);

以下是LINQPad中的结果:

Query results.

答案 1 :(得分:1)

这应该让玩家在所有尝试中都获得成功:

var vSuccessAllAttempts = (from d in lstAllDetails
                           group d by new {d.sPlayerId,d.sPlayerSuccess} into grp
                           where grp.Count() == 5 && grp.Key.sPlayerSuccess =="YES"
                           select grp.Key.sPlayerId);

答案 2 :(得分:1)

您也可以使用以下内容。

Func<IEnumerable<clsDetails>, int, IEnumerable<String>> successfulInNthAttempt =
    (p, n) =>
    p.Where(x => x.sPlayerSuccess == "YES" && x.iAttemptId == n)
        .Select(x => x.sPlayerId);

Func<IEnumerable<clsDetails>, int, bool, IEnumerable<String>>successfulInAllNAttempts =
    (p, n, isExact) =>
    p.Where(x => x.sPlayerSuccess == "YES")
        .GroupBy(y => new {y.sPlayerId, y.sPlayerSuccess})
        .Where(z => isExact? z.Count() == n: z.Count()>= n)
        .Select(x => x.Key.sPlayerId);

var attempt1 =successfulInNthAttempt(lstAllDetails, 1);
var attempt1Or2 = successfulInNthAttempt(lstAllDetails, 1).Union(successfulInNthAttempt(lstAllDetails, 2)).Distinct();
var atLeast3Attempts = successfulInAllNAttempts(lstAllDetails, 3, false);
var all5Attempts = successfulInAllNAttempts(lstAllDetails, 5, true);

Func<IEnumerable<clsDetails>, int, IEnumerable<String>> successfulInNthAttempt = (p, n) => p.Where(x => x.sPlayerSuccess == "YES" && x.iAttemptId == n) .Select(x => x.sPlayerId); Func<IEnumerable<clsDetails>, int, bool, IEnumerable<String>>successfulInAllNAttempts = (p, n, isExact) => p.Where(x => x.sPlayerSuccess == "YES") .GroupBy(y => new {y.sPlayerId, y.sPlayerSuccess}) .Where(z => isExact? z.Count() == n: z.Count()>= n) .Select(x => x.Key.sPlayerId); var attempt1 =successfulInNthAttempt(lstAllDetails, 1); var attempt1Or2 = successfulInNthAttempt(lstAllDetails, 1).Union(successfulInNthAttempt(lstAllDetails, 2)).Distinct(); var atLeast3Attempts = successfulInAllNAttempts(lstAllDetails, 3, false); var all5Attempts = successfulInAllNAttempts(lstAllDetails, 5, true);