【问题标题】:Sorting Array based on property of object on inner array根据内部数组上对象的属性对数组进行排序
【发布时间】:2017-12-27 17:48:27
【问题描述】:

我有一组从我们的 API 返回的帐户,这些帐户具有以下数据结构。

Accounts[] accounts = [
    {
        AccountNumber: 0000000001,
        PrimaryPerson: Virginia,
        PrimaryPersonNumber: 0001,
        PersonRoleCode: "OWN",
        PersonRoleDescription: "Owner",
        RoleOrder: 1
        PersonRoles: [
                         {
                             AccountRoleCode: "CO",
                             AccountRoleDescription: "Co-Owner",
                             PersonName: "David",
                             PersonNumber: 0002,
                             RoleOrder: 2
                         },
                         {
                             AccountRoleCode: "POA",
                             AccountRoleDescription: "Power of Attorney",
                             PersonName: "Clark",
                             PersonNumber: 0003,
                             RoleOrder: 6
                         }
                     ]
    },
    {
        AccountNumber: 0000000002,
        PrimaryPerson: Clark,
        PrimaryPersonNumber: 0003,
        PersonRoleCode: "OWN",
        PersonRoleDescription: "Owner",
        RoleOrder: 1
        PersonRoles: [
                         {
                             AccountRoleCode: "CO",
                             AccountRoleDescription: "Co-Owner",
                             PersonName: "Virginia",
                             PersonNumber: 0001,
                             RoleOrder: 2
                         },
                         {
                             AccountRoleCode: "POA",
                             AccountRoleDescription: "Power of Attorney",
                             PersonName: "David",
                             PersonNumber: 0002,
                             RoleOrder: 6
                         }
                     ]
    },   
    {
        AccountNumber: 0000000003,
        PrimaryPerson: David,
        PrimaryPersonNumber: 0002,
        PersonRoleCode: "OWN",
        PersonRoleDescription: "Owner",
        RoleOrder: 1
        PersonRoles: [
                         {
                             AccountRoleCode: "CO",
                             AccountRoleDescription: "Co-Owner",
                             PersonName: "Clark",
                             PersonNumber: 0003,
                             RoleOrder: 2
                         },
                         {
                             AccountRoleCode: "CO",
                             AccountRoleDescription: "Co-Owner",
                             PersonName: "Virginia",
                             PersonNumber: 0001,
                             RoleOrder: 2
                         },
                         {
                             AccountRoleCode: "POA",
                             AccountRoleDescription: "Power of Attorney",
                             PersonName: "Virginia",
                             PersonNumber: 0001,
                             RoleOrder: 6
                         }
                     ]
    }
];

我需要根据RoleOrderAccounts 对象本身和RoleOrder 对每个PersonRole 对象在每个PersonRoles[] 索引中的PersonRole 对象进行排序。

我尝试使用 LINQ 来实现,但我不确定为什么它不能正常工作。

这是我尝试过的以及我期望它做的事情。

IEnumerable<Account> sortedAccounts = accounts
    .OrderBy(acct => acct.PersonRoles
    .Where(role => role.PersNbr == 0001)
    .Select(x => x.RoleOrder)).ToList();

我希望它按PersonRoles[] 订购主要的accounts[],其中PersNbr 等于给定的PersNbr (0001),然后按RoleOrder 排序。

所以基本上我只想根据RoleOrder 对特定人的accounts[] 进行排序。

所以根据Virginia排序会得到Accounts[] accounts = [0000000001, 0000000003, 0000000002]

根据David排序会得到Accounts[] accounts = [0000000003, 0000000001, 0000000002]

我对 LINQ 所做的没有做任何事情(顺序保持不变),这让我认为我正在以正确的顺序进行查询。

如何编写 LINQ 查询来执行此操作,还是需要将其拆分为不同的查询?

【问题讨论】:

    标签: c# arrays linq sorting


    【解决方案1】:

    我被要求提供完整的答案,我们开始吧:

    首先,我想提请您注意您拥有的“设计漏洞”:如果您根本没有这个“人”会怎样?对于这种情况,我允许自己假设所有这些结果都会在最后显示。

    关于问题:问题的复杂性在于你需要进行两种不同的排序:在Account[]数组排序中,以及在每个账户内部的PersonRoles数组中,两者的排序逻辑相同。

    假设你的对象是可变的,我推荐下一个解决方案:

    IEnumerable<Account> sortedAccounts = accounts
                .Select(x => {
                    x.PersonRoles = x
                    .PersonRoles
                    .OrderBy(acct => {
                        if (acct.PersonNumber != 001)
                            return 999;
                        return acct.RoleOrder;
                    }).ToArray();
                    return x;
                })
                .OrderBy(acct => {                
                    var relevantRoles = acct.PersonRoles
                        .Where(role => role.PersonNumber == 0001)
                        .Select(x => x.RoleOrder);
                    if (relevantRoles.Any() == false)
                        return 999;
                    return relevantRoles.Max();
                    }
                ).ToList();
    

    说明: 我们从“select”语句开始,在该语句中,我们重新排序了每个帐户中 PersonRoles 数组的内部结构,这样更清晰,并且有助于更简单地执行帐户排序

    之后,我们按照同样的逻辑对accounts数组进行排序

    请注意,除了“return 999”语句之外,您还可以编写一些其他逻辑来解决 PersonRoles 数组中没有相关用户的情况。

    【讨论】:

      【解决方案2】:

      见:Sort a list and all its nested objects using Linq

      您可以在一个语句中做到这一点。在每个 LINQ 内部,您需要使用外部语句中的信息创建新对象。

      class Account
      {
          public int AccountNumber { get; set; }
          public Role[] Roles { get; set; }
      }
      
      class Role
      {
          public string State { get; set; }
          public int RoleOrder { get; set; }
      }
      
      Account[] accounts = new Account[3];
              accounts[0] = new Account { AccountNumber = 1, Roles = new 
      Role[2] { new Role { State = "AK", RoleOrder = 2 }, new Role { State = 
      "CO", RoleOrder = 1 } } };
              accounts[1] = new Account { AccountNumber = 3, Roles = new 
      Role[2] { new Role { State = "NY", RoleOrder = 66 }, new Role { State = 
      "FL", RoleOrder = 5 } } };
              accounts[2] = new Account { AccountNumber = 2, Roles = new 
      Role[2] { new Role { State = "CA", RoleOrder = 9 }, new Role { State = 
      "AZ", RoleOrder = 8 } } };
      
      IEnumerable<Account> info = accounts
          .Select(x => new Account { 
              AccountNumber = x.AccountNumber
              , Roles = x.Roles.OrderBy(y => y.RoleOrder).ToArray() 
          }
          ).Where(x => x.AccountNumber == 2);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-23
        • 2015-06-17
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        • 2020-04-21
        • 2012-10-22
        相关资源
        最近更新 更多