Упорядочить по вложенному объекту в массиве - PullRequest
1 голос
/ 28 октября 2019

Я застрял на одной вещи, пытаясь взять 3 лучших производителя по numberOfCars, и, чтобы сделать то же самое с cars: [], взять 3 лучших по numberoOfCars

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)

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Переберите ключи во внешнем объекте, упорядочите эти ключи по количеству автомобилей, связанных с этим ключом во внешнем объекте, затем выберите первые 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();

Пример на jsfiddle

Кредит этого ответа от VLAZ за помощь в том, как отфильтровать элементы объекта по порядку его значений.

0 голосов
/ 28 октября 2019

Я думаю, это должно быть примерно так:

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);
...