【问题标题】:Order by nested object property inside a array按数组内的嵌套对象属性排序
【发布时间】:2026-02-08 09:15:02
【问题描述】:

我被困在试图通过 numberOfCars 获得前 3 名制造商的一件事上,并且为了对 cars: [] 做同样的事情,通过 numberoOfCars 获得前 3 名

audi: {
  cars: [], 
  collectionName: '',
  numberOfCars: 0
}

我可以像 lodash 一样做第一级

_.take(_.orderBy(modelData, 'numberoOfCars', 'desc'), 3)

但我在前面提到的汽车阵列上做同样的事情时迷失了。

const mock = []

for (let i = 0; i < 140; i++) {
  let manufacturerName
  let name

  if (i < 20) {
    manufacturerName = 'Audi'
    name = 'A6'
  } else if (i > 19 && i < 40) {
    manufacturerName = 'BMW'
    name = '420 GC'
  } else if (i > 19 && i < 40) {
    manufacturerName = 'Mercedes'
    name = 'AMG'
  } else if (i > 39 && i < 60) {
    manufacturerName = 'Mazda'
    name = '6'
  } else if (i > 59 && i < 80) {
    manufacturerName = 'Volvo'
    name = 'V90'
  } else if (i > 79 && i < 100) {
    manufacturerName = 'Renault'
    name = 'Model'
  } else if (i > 99 && i < 120) {
    manufacturerName = 'Lamborghini'
    name = 'Aventador'
  } else if (i > 119 && i < 140) {
    manufacturerName = 'Volkswagen'
    name = 'Golf'
  }

  mock.push({
    id: i,
    name: name,
    displayName: 'display-name ' + Math.floor(Math.random() * 10),
    manufacturer: manufacturerName,
    numberoOfCars: Math.floor(Math.random() * 100000),
  })
}

const dataModel = mock.reduce((accumulator, currentValue) => {
  const key = currentValue.manufacturer

  if (accumulator[key] === undefined) {
    accumulator[key] = {
      collectionName: '',
      numberoOfCars: 0,
      cars: []
    }
  }

  if (accumulator[key].collectionName === '') {
    accumulator[key].collectionName = currentValue.manufacturer
  }

  if (currentValue.numberoOfCars !== undefined) {
    accumulator[key].numberoOfCars += currentValue.numberoOfCars
  }

  if (currentValue.numberoOfCars !== undefined) {
    accumulator[key].cars.push({
      name: currentValue.name,
      numberOfCars: currentValue.numberoOfCars
    })
  }

  return accumulator
}, {})

console.log(dataModel)

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    遍历外部对象中的键,按照外部对象中与该键关联的汽车数量对这些键进行排序,然后选择前 3 个键。

    然后,将每个键归约为一个对象,该对象克隆与该键关联的值并在该值中对汽车进行排序并取前 3 个:

    var filtered = _.chain(dataModel)
        .keys()
        .orderBy(k=>dataModel[k].numberOfCars, 'desc')
        .take(3)
        .reduce((coll,k)=>{
            coll[k] = _.clone(dataModel[k]);
            coll[k].cars = _.chain(coll[k].cars)
                .orderBy('numberOfCars', 'desc')
                .take(3)
                .value();
            return coll;
        }, {})
        .value();
    

    Example on jsfiddle

    感谢 VLAZ 的 this answer,获取有关如何通过对对象的值进行排序来过滤对象的项目的帮助。

    【讨论】:

    • 谢谢。我试图理解一件事,有没有办法在没有第二次减少的情况下做到这一点,比如为什么有必要这样做?不要误会,这是我的学习过程:)
    • @Dejan.S 第二reduce?我只用了一个reduce
    【解决方案2】:

    我想应该是这样的:

    const cars = Object.keys(dataModel).reduce((acc, item) => {
      const collection = dataModel[item]
      return acc.concat(collection.cars)
    }, []);
    
    const top3cars = _.take(_.orderBy(cars, 'numberOfCars', 'desc'), 3);
    

    【讨论】: