Фильтр массива объектов JavaScript по минимальному значению атрибута - PullRequest
0 голосов
/ 01 ноября 2018

Мне нужно отфильтровать этот массив объектов по минимальному значению атрибута rest. Это один из способов сделать это. Есть ли другие способы?

Переменная 'data' является результатом цепной функции. Есть ли другой способ сделать это без повторного вызова переменной data в функции Math.min ().

let data = 
[ { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } ]

let result = data.filter(e=> e.rest === Math.min(...data.map(f=>f.rest) ) );
console.log(result);

// result is
//[ { size: 5, qty: 2, rest: 0 },
//  { size: 2, qty: 5, rest: 0 },
//  { size: 1, qty: 10, rest: 0 }]

Ответы [ 4 ]

0 голосов
/ 01 ноября 2018

имо. самое простое / лучшее решение - это то, которое @CertainPerformance дал вам.

Просто хотел добавить другое решение с линейным временем выполнения (которое действительно повторяется только один раз по массиву)

let data = [
  { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } 
];

let result = data.reduce((result, item) => {
  let minRest = result.length? result[0].rest: item.rest;

  if (item.rest < minRest) {
    minRest = item.rest;
    result.length = 0;
  }

  if (item.rest === minRest) {
    result.push(item);
  }

  return result;
}, []);

console.log(result);

@ mathieux51 дал мне еще одну идею, как вы можете сделать это внутри цепочки методов, но читаемость / ясность / намерение не так хороши, как с другими подходами:

let data = [
  { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } 
];

let result = data.sort((a, b) => a.rest - b.rest)
                 .filter((item, index, array) => item.rest === array[0].rest);

console.log(result);
0 голосов
/ 01 ноября 2018

Звучит так, будто вы хотите отсортировать список. Я бы сделал это следующим образом:

const result = data.sort((a, b) => a.rest - b.rest)
0 голосов
/ 01 ноября 2018

Самый простой способ - извлечь функцию min из фильтра следующим образом:

let min = Math.min(...data.map(item => item.rest))

Это гораздо эффективнее, так как мы больше не перебираем данные, чтобы найти мин для каждой итерации фильтра.

Теперь у нас есть n * 2 прохода вместо n ^ 2 прохода. (n - размер вашего набора данных, в данном случае 5)

Полный пример ниже:

   let data = [ 
     { size: 5, qty: 2, rest: 0 },
     { size: 2, qty: 5, rest: 0 },
     { size: 1, qty: 10, rest: 0 },
     { size: 3, qty: 3, rest: 1 },
     { size: 4, qty: 2, rest: 2 } 
   ]

  let min = Math.min(...data.map(item => item.rest))
  let result = data.filter(item => item.rest === min)
  console.log(result)

Надеюсь, это поможет!

Lloyd

0 голосов
/ 01 ноября 2018

data.map внутри data.filter равно O(N^2); для решения O(N) итерируйте заранее data для расчета минимума, затем filter к этому минимуму:

let data = 
[ { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } ];
const minRest = Math.min(...data.map(({ rest }) => rest));

let result = data.filter(({ rest }) => rest === minRest);
console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...