Сопоставьте входной массив и получите отфильтрованный массив объекта в качестве результата

#javascript #arrays #reactjs #loops #object

#javascript #массивы #reactjs #циклы #объект

Вопрос:

У меня есть приведенные ниже данные, поступающие из серверной части.

 priorities: [ 'get license', 'enroll college' ];
  

Теперь у меня есть список объектов, жестко закодированных во внешнем интерфейсе.

 studentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  },
  {
   prioritiesTitle: "give exams",
   prioritiesDescription: "study hard for the exams"
  }
]
  

В любой момент времени я получу 2 приоритета в качестве ответа сервера. Мне нужно выполнить поиск в моем жестко закодированном массиве объектов и получить окончательные данные следующим образом.

 mappedStudentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  }
]
  

Может кто-нибудь, пожалуйста, подсказать мне, как этого добиться?

Ответ №1:

Это можно просто сделать с помощью Array.filter amp; Array.includes .

Используя Array.includes , вы можете проверить, включен ли элемент в массив или нет, и используя Array.filter , вы можете получить отфильтрованный результат, который удовлетворяет условию.

 const priorities = [ 'get license', 'enroll college' ];

const studentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  },
  {
   prioritiesTitle: "give exams",
   prioritiesDescription: "study hard for the exams"
  }
];

const result = studentPriorities.filter(({ prioritiesTitle }) => priorities.includes(prioritiesTitle));
console.log(result);  

Ответ №2:

Я предпочитаю использовать indexOf, потому что includes не поддерживается старыми и некоторыми новыми браузерами

const результат = studentPriorities .filter(({ prioritestitle }) => (priorities.indexOf(prioritestitle) !== -1));

console.log(результат);

Ответ №3:

Вы можете использовать Array.prototype.flatMap массив, который вы получаете от серверной части, а затем использовать Array.prototype.filter для записей данных. Функция может выглядеть следующим образом:

 /** @param {string[]} priorities the titles you want to match */
function filterByPriorities (...priorities) {
  return priorities.flatMap(priority => studentPriorities.filter(({ prioritiesTitle }) => prioritiesTitle === priority))
}
  

Основная логика:

  • для каждой строки в input
    • отфильтруйте dataset для всех элементов, где:
      • prioritiesTitle Матчи input
  • сгладить результат предыдущей операции
  • return результат

Теперь здесь не так много преимуществ, но если данные усложняются, использование a for...of -loop часто является хорошей идеей. Приведенная ниже функция даст тот же результат, но для сложных операций это, как правило, легче понять и поддерживать.

  • для каждого entry в dataset
    • если input включает заголовок записи
      • нажмите entry на out-array
  • Возврат out-array
 /** @param {string[]} priorities the titles you want to match */
function filter2 (...priorities) {
  const out = []
  for (const { prioritiesTitle, ...rest } of studentPriorities) {
    if (priorities.includes(prioritiesTitle)) out.push({ prioritiesTitle, ...rest })
  }
  return out
}
  

ожидаемый результат для обоих:

 [
  {
    prioritiesTitle: 'get license',
    prioritiesDescription: 'go to DMV and get your license'
  },
  {
    prioritiesTitle: 'enroll college',
    prioritiesDescription: 'gather fees and enroll for college'
  }
]
  

О нас Array.prototype.includes

Приличный мусор разработчиков рекомендует использовать Array.prototype.indexOf вместо Array.prototype.includes , потому .includes что он доступен не во всех когда-либо созданных браузерах. Но важно отметить несколько моментов:

  • каждый обычный браузер * (включая их аналоги для мобильных устройств) уже Array.prototype.includes почти 5 лет
  • в зависимости от движка, .indexOf для больших наборов данных это может означать значительное снижение скорости по сравнению с .includes (от немного медленнее, если элемент находится в конце результата, До в 1000 раз меньше operations/s в v8 (Chrome, nodejs и т. Д.), Когда элемент близок к началу массива.src)
  • если вам специально не нужно поддерживать IE, нет особых причин не использовать .includes , поскольку подавляющее большинство пользователей будут использовать браузер, который его поддерживает.

* обычный браузер -> браузер с одним из обычных JS-движков

  • v8 -> любой браузер на базе Chromium (Opera, Edge, Chrome)
  • spidermonkey -> FireFox
  • JavaScriptCore -> safari и союзники