【问题标题】:How to sort a nested array of objects in javascript?如何在javascript中对嵌套的对象数组进行排序?
【发布时间】:2019-09-30 00:21:26
【问题描述】:

我有一个对象数组:

entities: [
  {
    name: "zBroomsticks PTY",
    id: 34098365,
    entityType: "personal",
    facilities: [
      {
        type: "Home loan",
        account: "032654 987465",
        existing: true,
        modified: "04/12/2018",
        limit: 100000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 200000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  },
  {
    name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
    id: 34098365,
    entityType: "business",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018" ,
        limit: 10000
      }
    ]
  },
  {
    name: "Mr Jack",
    id: 34098365,
    entityType: "mixed",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  }
]

我想按特定顺序排序:

  1. entity.name:按字母升序排列。

  2. entity.entityType: 1. 个人 2. 商务 3. 混合

  3. entity.facilities.limit:降序

这是我目前得到的代码:

sortData(entities) {
    var order = {
      entityType: { personal: 2, business: 1 }
    };

    return entities.map(ent =>
      entities.sort(
        (a, b) =>
          a.name - b.name ||
          order.entityType[a.facilities.entityType] - order.entityType[b.facilities.entityType]
      )
    );
}

我知道如何执行名称排序,但找不到 2 和 3 的方法?

Link to code

【问题讨论】:

  • limit 只是为了对facilities 数组进行排序,还是你希望它也会影响到外部数组entities?
  • 只是设施数组。

标签: javascript arrays reactjs sorting


【解决方案1】:

首先,要通过names 订购,您可以使用localeCompare()。其次,facilities 数组中没有属性 entityType,但您正在尝试访问它。现在,一种解决方案是首先使用Array.map() 来获取一个新数组,其中facilities 数组按limit 属性排序,然后您可以将map() 返回的新数组首先按names 排序,然后再排序通过entityType 属性,如下所示:

const input = [{name:"zBroomsticks PTY",id:34098365,entityType:"personal",facilities:[{type:"Home loan",account:"032654 987465",existing:true,modified:"04/12/2018",limit:100000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:200000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr John Doe -3409865, Mrs Jane Doe -34098365",id:34098365,entityType:"business",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr Jack",id:34098365,entityType:"mixed",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr Jack",id:34098365,entityType:"personal",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]}];

let order = {
  entityType: {personal:1, business:2, mixed:3}
};

function sortData(entities)
{    
    let limitOrder = entities.map(e =>
    {
        e.facilities.sort((a, b) => b.limit - a.limit);
        return e;
    });

    return limitOrder.sort((a, b) =>
    {
        return a.name.localeCompare(b.name) ||
               order.entityType[a.entityType] - order.entityType[b.entityType];
    });
}

console.log(sortData(input));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

注意,我使用不同的entityType 复制了与name: "Mr Jack" 相关的对象,因此您可以看到当有两个等于names 的对象时算法的执行情况。

【讨论】:

    【解决方案2】:

    按照1、2 和最后3 的优先顺序对数组进行排序

    2 条件,您可以使用index 对象来映射entityType 及其权重。

    3 因为要按descending order 排序,所以在facilities 列表中找到最小的limit 值并与其他项进行比较。

    let entities = [
      {
        name: "zBroomsticks PTY",
        id: 34098365,
        entityType: "personal",
        facilities: [
          {
            type: "Home loan",
            account: "032654 987465",
            existing: true,
            modified: "04/12/2018",
            limit: 100000
          },
          {
            type: "Credt card",
            account: "032654 987465",
            existing: false,
            modified: "04/12/2018",
            limit: 200000
          },
          {
            type: "Credt card",
            account: "032654 987465",
            existing: false,
            modified: "04/12/2018",
            limit: 10000
          },
          {
            type: "Credt card",
            account: "032654 987465",
            existing: false,
            modified: "04/12/2018",
            limit: 10000
          }
        ]
      },
      {
        name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
        id: 34098365,
        entityType: "business",
        facilities: [
          {
            type: "Overdraft",
            account: "032654 987465",
            existing: false,
            modified: "04/12/2018",
            limit: 10000
          }
        ]
      },
      {
        name: "Mr Jack",
        id: 34098365,
        entityType: "mixed",
        facilities: [
          {
            type: "Overdraft",
            account: "032654 987465",
            existing: false,
            modified: "04/12/2018",
            limit: 10000
          }
        ]
      }
    ];
    
    
    const entityIndex = { personal: 1, business: 2, mixed: 3 };
    
    let result = entities.sort((a, b) => {
      if (a.name > b.name) return -1;
      if (a.name < b.name) return 1;
    
      let et = entityIndex[a.entityType] - entityIndex[b.entityType];
      if (et != 0) return et;
    
      const aMinLimit = Math.min(...a.facilities.map(i => i.limit));
      const bMinLimit = Math.min(...b.facilities.map(i => i.limit));
    
      return bMinLimit - aMinLimit;
    
    })
    
    console.log(JSON.stringify(result));
    

    【讨论】:

      【解决方案3】:

      试试

      eType = {personal:1, business:2, mixed:3};
      
      entities.sort((a,b) => {
         if(a.name>b.name) return 1;
         if(a.name<b.name) return -1;
      
         let et=eType[a.entityType]-eType[b.entityType];
         return et;   
      })
      
      entities.forEach(e=> e.facilities.sort((a,b)=> b.limit - a.limit ))
      

      let entities = [
              {
                name: "zBroomsticks PTY",
                id: 34098365,
                entityType: "personal",
                facilities: [
                  {
                    type: "Home loan",
                    account: "032654 987465",
                    existing: true,
                    modified: "04/12/2018",
                    limit: 100000
                  },
                  {
                    type: "Credt card",
                    account: "032654 987465",
                    existing: false,
                    modified: "04/12/2018",
                    limit: 200000
                  },
                  {
                    type: "Credt card",
                    account: "032654 987465",
                    existing: false,
                    modified: "04/12/2018",
                    limit: 10000
                  },
                  {
                    type: "Credt card",
                    account: "032654 987465",
                    existing: false,
                    modified: "04/12/2018",
                    limit: 10000
                  }
                ]
              },
              {
                name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
                id: 34098365,
                entityType: "business",
                facilities: [
                  {
                    type: "Overdraft",
                    account: "032654 987465",
                    existing: false,
                    modified: "04/12/2018" ,
                    limit: 10000
                  }
                ]
              },
      {
                name: "Mr Jack",
                id: 34098365,
                entityType: "mixed",
                facilities: [
                  {
                    type: "Overdraft",
                    account: "032654 987465",
                    existing: false,
                    modified: "04/12/2018",
                    limit: 10000
                  }
                ]
              }
            ];
            
            
      eType = {personal:1, business:2, mixed:3};
      
      entities.sort((a,b) => {
         if(a.name>b.name) return 1;
         if(a.name<b.name) return -1;
         
         let et=eType[a.entityType]-eType[b.entityType];
         return et;   
      })
      
      entities.forEach(e=> e.facilities.sort((a,b)=> b.limit - a.limit ))
      
      console.log(entities);

      【讨论】:

        猜你喜欢
        • 2012-06-22
        • 2016-07-01
        • 2015-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-01
        相关资源
        最近更新 更多