фильтровать массив и получать максимальные значения вложенного массива каждого набора объектов в javascrip - PullRequest
1 голос
/ 28 мая 2020
• 1000
var data = [
      {
        'product':'laptop',
        'count_buyer':3,
        'buyers':[
              { 'name': 'Vins', 'purchase_amount': 27 },
              { 'name': 'Jan', 'purchase_amount': 38 },
              { 'name': 'Alex', 'purchase_amount': 80 },
        ]
      },
      {
        'product':'televisor',
        'count_buyer':2,
        'buyers':[
              { 'name': 'Carl', 'purchase_amount': 25 },
              { 'name': 'Digi', 'purchase_amount': 40 }
        ]
      },
      {
        'product':'ropa varon',
        'count_buyer':0,
        'buyers':[]
      }
    ];

сначала я хочу отфильтровать объекты, которые у них есть в их массиве покупателей.

[     
      {
        'product':'laptop',
        'count_buyer':3,
        'buyers':[
              { 'name': 'Vins', 'purchase_amount': 27 },
              { 'name': 'Jan', 'purchase_amount': 38 },
              { 'name': 'Alex', 'purchase_amount': 80 },
        ]
      },
      {
        'product':'televisor',
        'count_buyer':2,
        'buyers':[
              { 'name': 'Carl', 'purchase_amount': 25 },
              { 'name': 'Digi', 'purchase_amount': 40 }
        ]
      },
]

затем отфильтровать максимальное количество покупателей, чьим условием является максимальное количество покупок

[     
      {
        'product':'laptop',
        'count_buyer':3,
        'buyers':[
              { 'name': 'Alex', 'purchase_amount': 80 },
        ]
      },
      {
        'product':'televisor',
        'count_buyer':2,
        'buyers':[
              { 'name': 'Digi', 'purchase_amount': 40 }
        ]
      },
]

это мой код

var data = [
  {
    'product':'laptop',
    'count_buyer':3,
    'buyers':[
          { 'name': 'Vins', 'purchase_amount': 27 },
          { 'name': 'Jan', 'purchase_amount': 38 },
          { 'name': 'Alex', 'purchase_amount': 80 },
    ]
  },
  {
    'product':'televisor',
    'count_buyer':2,
    'buyers':[
          { 'name': 'Carl', 'purchase_amount': 25 },
          { 'name': 'Digi', 'purchase_amount': 40 }
    ]
  },
  {
    'product':'ropa varon',
    'count_buyer':0,
    'buyers':[]
  }
];
var filter0 = data.filter(count=> count.count_buyer > 0 )
var max = filter0.filter(buye => buye.buyers.reduce(function (prev, current) {
   return (prev.purchase_amount > current.purchase_amount) ? prev : current
}));
console.log(max)

но результат такой

[     
      {
        'product':'laptop',
        'count_buyer':3,
        'buyers':[
              { 'name': 'Vins', 'purchase_amount': 27 },
              { 'name': 'Jan', 'purchase_amount': 38 },
              { 'name': 'Alex', 'purchase_amount': 80 },
        ]
      },
      {
        'product':'televisor',
        'count_buyer':2,
        'buyers':[
              { 'name': 'Carl', 'purchase_amount': 25 },
              { 'name': 'Digi', 'purchase_amount': 40 }
        ]
      },
]

Как я могу получить этот результат?

[     
      {
        'product':'laptop',
        'count_buyer':3,
        'buyers':[
              { 'name': 'Alex', 'purchase_amount': 80 },
        ]
      },
      {
        'product':'televisor',
        'count_buyer':2,
        'buyers':[
              { 'name': 'Digi', 'purchase_amount': 40 }
        ]
      },
]

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

После .reduce, как только вы найдете покупателя с максимальным purchase_amount, создайте новый массив buyers с этим результатом в качестве одного элемента.

Используя .map и объект spread / rest, чтобы не изменять существующие данные, вы можете использовать:

var data = [
  {
    'product':'laptop',
    'count_buyer':3,
    'buyers':[
          { 'name': 'Vins', 'purchase_amount': 27 },
          { 'name': 'Jan', 'purchase_amount': 38 },
          { 'name': 'Alex', 'purchase_amount': 80 },
    ]
  },
  {
    'product':'televisor',
    'count_buyer':2,
    'buyers':[
          { 'name': 'Carl', 'purchase_amount': 25 },
          { 'name': 'Digi', 'purchase_amount': 40 }
    ]
  },
  {
    'product':'ropa varon',
    'count_buyer':0,
    'buyers':[]
  }
];

const output = data
  .filter(({ buyers }) => buyers.length)
  .map(({ buyers, ...rest }) => {
    const maxBuyer = buyers.reduce((a, b) => a.purchase_amount > b.purchase_amount ? a : b);
    return { ...rest, buyers: [maxBuyer] };
  });
console.log(output);
0 голосов
/ 29 мая 2020

Я написал библиотеку rubico , чтобы упростить метод, который мы собираемся использовать, чтобы сделать это за один проход: преобразователи . Если вы не знаете, что это такое, я написал Cra sh курс здесь . Сначала я покажу вам, как это сделать за два прохода, т.е.

[...products] => [...products_with_buyers]

[...products_with_buyers] => [...products_with_max_buyer].

const { transform, pipe, assign, map, filter, reduce, get, gt } = require('rubico')

const getMaxBuyer = (y, xi) => y.purchase_amount > xi.purchase_amount ? y : xi

const getProductsWithMaxBuyer = pipe([
  filter(gt(get('buyers.length'), 0)), // [...products] => [...products_with_buyers]
  map(assign({
    buyers: pipe([
      get('buyers'), // product => product.buyers
      reduce(getMaxBuyer), // buyers => [max_buyer]
    ]), // assign [max_buyer] the result to the 'buyers' property on the product
  })) // [...products_with_buyers] => [...products_with_max_buyer]
])

getProductsWithMaxBuyer(data) /* creates an intermediate array `product_with_buyers`
[
  {
    product: 'laptop',
    count_buyer: 3,
    buyers: { name: 'Alex', purchase_amount: 80 }
  },
  {
    product: 'televisor',
    count_buyer: 2,
    buyers: { name: 'Digi', purchase_amount: 40 }
  }
]
*/

Вот как вы это делаете за один проход. pass.

[...products] => [...products_with_max_buyer]

transform(
  getProductsWithMaxBuyer,
  [],
)(data) /* => [ does not create any intermediate arrays, everything is one pass
  {
    product: 'laptop',
    count_buyer: 3,
    buyers: { name: 'Alex', purchase_amount: 80 }
  },
  {
    product: 'televisor',
    count_buyer: 2,
    buyers: { name: 'Digi', purchase_amount: 40 }
  }
] */

Разница здесь в контексте, в котором используются функции Rubico. Они достаточно «умны», чтобы знать, следует ли им вести себя как преобразователи. Если вы хотите узнать больше, ознакомьтесь с intro и docs

...