在对象数组内对数组进行排序

时间:2019-12-26 23:08:04

标签: javascript arrays

如果我有大量的数组,排序和返回前5个项目的最快方法是什么?

对象数组:

[
  {
    "name" : "placeA",
    "menus" : [ 
        {
            "sold" : 5,
            "name" : "menuA"
        }, 
        {
            "sold" : 20,
            "_id" : "menuB"
        }, 
        {
            "sold" : 1000,
            "_id" : "menuC"
        }
    ]
  },
  {
    "name" : "placeB",
    "menus" : [ 
        {
            "sold" : 300,
            "name" : "menuD"
        }, 
        {
            "sold" : 400,
            "_id" : "menuE"
        }, 
        {
            "sold" : 50,
            "_id" : "menuF"
        }
    ]
  },
  {
    "name" : "placeC",
    "menus" : [ 
        {
            "sold" : 1500,
            "name" : "menuG"
        }, 
        {
            "sold" : 450,
            "_id" : "menuH"
        }, 
        {
            "sold" : 75,
            "_id" : "menuI"
        }
    ]
  }
]

预期输出:

[
    {
      "sold" : 1500,
      "name" : "menuG"
    },
    {
      "sold" : 1000,
      "_id" : "menuC"
    },
    {
      "sold" : 450,
      "_id" : "menuH"
    },
    {
      "sold" : 400,
      "_id" : "menuE"
    },
    {
      "sold" : 300,
      "name" : "menuD"
    } 
]

我唯一想到的可能方法是创建一个填充所有菜单的数组,然后对菜单进行排序,然后对前5个项目进行切片。我认为这种方式不足以在实际用例中对庞大的数组集合进行排序。

3 个答案:

答案 0 :(得分:2)

您可以使用.map().reduce().concat().sort().slice()

var arr = [{
    "name": "placeA",
    "menus": [{
        "sold": 5,
        "name": "menuA"
      },
      {
        "sold": 20,
        "_id": "menuB"
      },
      {
        "sold": 1000,
        "_id": "menuC"
      }
    ]
  },
  {
    "name": "placeB",
    "menus": [{
        "sold": 300,
        "name": "menuD"
      },
      {
        "sold": 400,
        "_id": "menuE"
      },
      {
        "sold": 50,
        "_id": "menuF"
      }
    ]
  },
  {
    "name": "placeC",
    "menus": [{
        "sold": 1500,
        "name": "menuG"
      },
      {
        "sold": 450,
        "_id": "menuH"
      },
      {
        "sold": 75,
        "_id": "menuI"
      }
    ]
  }
]

var newarr = arr.map(v => v.menus).reduce((a, c) => a.concat(c));
console.log(newarr.sort((a,b) => b.sold - a.sold).slice(0,5));

不过,我不确定这是否是最快的方法。

答案 1 :(得分:1)

除了Yousername所说的外,您还可以flat

array
.map((a) => a.menus) // select menus
.flat() // all sub-array elements concatenated
.sort((a, b) => b.sold - a.sold) // sort by key sold
.slice(0,5) // select the first 5

答案 2 :(得分:1)

您可以使用.reduce(),并用spread operator对其进行清理,以使阵列变平,而destructing可以直接进入“菜单”阵列

const data = [{name:"placeA",menus:[{sold:5,name:"menuA"},{sold:20,_id:"menuB"},{sold:1e3,_id:"menuC"}]},{name:"placeB",menus:[{sold:300,name:"menuD"},{sold:400,_id:"menuE"},{sold:50,_id:"menuF"}]},{name:"placeC",menus:[{sold:1500,name:"menuG"},{sold:450,_id:"menuH"},{sold:75,_id:"menuI"}]}];

let newArray = data
  .reduce((acc, {menus}) => [...acc, ...menus], [])
  .sort((a, b) => b.sold - a.sold);

console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }