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

#javascript #node.js #algorithm #data-structures #javascript-objects

Вопрос:

У меня есть массив объектов, пример:

 [  {  "fName": "Jon",  "lName": "Doe",  "age": "30",  "shirtSize": "M"  },  {  "fName": "Jane",  "lName": "Foe",  "age": "25",  "shirtSize": "M"  },  ... ]  

У меня также есть список ключей, пример:

 ["age", "shirtSize"]  

Я хочу взять массив объектов и построить новый массив объектов, соответствующих массиву списка ключей, эффективно фильтруя массив объектов, чтобы в нем были только нужные мне пары ключ/значение. Выше приведены примеры, и реальные наборы данных, конечно, более подробные. Я грубо ввел его в свой алгоритм ниже, и, как и ожидалось, он вообще не очень эффективен из-за моего цикла внутри карты. Мой результат выглядит так:

 [  {  "age": "30",  "shirtSize": "M"  },  {  "age": "25",  "shirtSize": "M"  },  ...  ]  

Я не использую ничего подобного lodash. Как я могу улучшить эту производительность?

 const data = [  {  "fName": "Jon",  "lName": "Doe",  "age": "30",  "shirtSize": "M"  },  {  "fName": "Jane",  "lName": "Foe",  "age": "25",  "shirtSize": "M"  } ]; const keyList = ["age", "shirtSize"];  const filteredDataset = data.map((elem) =gt; {  let tempHolder = {};  for (let key of keyList) {  tempHolder[key] = elem[key];  }  return tempHolder; });  return filteredDataset;  

Комментарии:

1. Я не думаю, что вы можете сделать это без двух петель или, по крайней мере, эквивалента двух петель. По одному для каждого элемента data , по одному для каждого элемента keylist . Однако вы должны объявить tempHolder внутри карты, иначе вы будете добавлять один и тот же объект в массив снова и снова.

2. «петля внутри карты» — по порядку, лучше вы ничего не можете сделать. Однако ваш код кажется ошибочным — например tempHolder , кажется, что всегда один и тот же объект. Я не думаю, что ваш опубликованный результат-это то, что вы на самом деле получаете из этого кода.

3. Этот код неверен. Поскольку tempHolder он не создается заново для каждого объекта, он будет выводить отфильтрованные результаты только одного объекта вместо двух.

4. Спасибо всем, мой рукописный пример был объявлен tempHolder в неправильной области

Ответ №1:

 var results = []; for(var person of data){  var obj = {};  for(var key of keyList){  obj[key] = person[key];  }  results.push(obj); }  

Первый цикл перебирает данные, а внутренний цикл перебирает список ключей и добавляет эти атрибуты во временный объект, который затем перемещается в массив результатов.

РЕДАКТИРОВАТЬ: Ваш код в основном такой же, вы просто используете карту для итерации вместо цикла for…of.

Ответ №2:

Вы можете выразить тот же алгоритм более декларативно:

 const select = (props) =gt; (objs) =gt;  objs .map (o =gt; Object .fromEntries (props .map (p =gt; [p, o[p]])))  const items = [{fName: "Jon", lName: "Doe", age: "30", shirtSize: "M"}, {fName: "Jane", lName: "Foe", age: "25", shirtSize: "M"}]  console .log (select (["age", "shirtSize"]) (items))