реагировать фильтр первые три каждого типа - PullRequest
0 голосов
/ 24 апреля 2020

Я делаю реактивный проект, и в какой-то момент у меня есть API, который возвращает следующее:

APIresult = [
    {
        category: "first",
        value: "honey"
    },
    {
        category: "first",
        value: "milk"
    },
    {
        category: "first",
        value: "biscuit"
    },
    {
        category: "first",
        value: "tea"
    },
    {
        category: "first",
        value: "coffee"
    },
    {
        category: "second",
        value: "pillow"
    },
    {
        category: "second",
        value: "bedsheet"
    },
    {
        category: "second",
        value: "tv"
    },
    {
        category: "second",
        value: "fridge"
    },
    {
        category: "second",
        value: "airconditioner"
    },

]

Я хочу отфильтровать этот массив, чтобы получить первые три из каждой категории. ie, результат, который я ожидаю, равен

APIresult = [
    {
        category: "first",
        value: "honey"
    },
    {
        category: "first",
        value: "milk"
    },
    {
        category: "first",
        value: "biscuit"
    },
    {
        category: "second",
        value: "pillow"
    },
    {
        category: "second",
        value: "bedsheet"
    },
    {
        category: "second",
        value: "tv"
    }

]

Я знаю, что должен выполнить APIresults.filter, но как мне ограничить результат только первыми 3 из каждого типа?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Вы можете использовать Array.prototype.reduce для фильтрации и группировки вашего массива так, чтобы были доступны первые три элемента каждой категории, а затем снова объединить результаты в массиве

const APIresult = [
    {
        category: "first",
        value: "honey"
    },
    {
        category: "first",
        value: "milk"
    },
    {
        category: "first",
        value: "biscuit"
    },
    {
        category: "first",
        value: "tea"
    },
    {
        category: "first",
        value: "coffee"
    },
    {
        category: "second",
        value: "pillow"
    },
    {
        category: "second",
        value: "bedsheet"
    },
    {
        category: "second",
        value: "tv"
    },
    {
        category: "second",
        value: "fridge"
    },
    {
        category: "second",
        value: "airconditioner"
    },

]

const res = [].concat(...Object.values(APIresult.reduce((acc, item) => {
   if(acc[item.category] && acc[item.category].length < 3) {
      acc[item.category].push(item);
   } else if(!acc[item.category]) {
       acc[item.category] = [item];
   }
   return acc;
}, {})))
console.log(res);
0 голосов
/ 24 апреля 2020

Интересная проблема здесь - другое решение, упакуйте их в 2 массива, а затем просто отфильтруйте эти массивы до первых 3 записей

arr = [{
    category: "first",
    value: "honey"
  },
  {
    category: "first",
    value: "milk"
  },
  {
    category: "first",
    value: "biscuit"
  },
  {
    category: "first",
    value: "tea"
  },
  {
    category: "first",
    value: "coffee"
  },
  {
    category: "second",
    value: "pillow"
  },
  {
    category: "second",
    value: "bedsheet"
  },
  {
    category: "second",
    value: "tv"
  },
  {
    category: "second",
    value: "fridge"
  },
  {
    category: "second",
    value: "airconditioner"
  },

]

const res = arr.reduce((acc, x, i) => {
  const index = acc.findIndex(y => y.length && y[y.length - 1].category === x.category);
  if (index < 0) {
    acc = [...acc, [x]];
  } else {
    acc[index].push(x)
  }
  return acc
}, []).flatMap(x => x.filter((y, i) => i < 3));

console.log(res)
...