Как сопоставить массив с новым отдельным объектом в Angular 8?

#javascript #angular #angular8

#javascript #angular #angular8

Вопрос:

Я делаю это:

 const rawValues = this.filterList.map(s => {
     return {[s.filterLabel]: s.selectedOption}
  });
 

filterList переменная имеет этот тип:

 export interface SelectFilter {
  filterLabel: string;
  options: Observable<any>;
  selectedOption: string;
}
 

теперь rawValues сопоставляется следующим образом:

 [
{filterLabel: selectedOption},
{filterLabel: selectedOption},
{filterLabel: selectedOption}
]
 

итак, это массив моих новых объектов,

но я хочу ОДИН объект, поэтому конечный результат должен быть:

 {
filterLabel: selectedOption,
filterLabel: selectedOption,
filterLabel: selectedOption
}
 

ОБРАТИТЕ внимание, что « filterLabel » всегда будет уникальным.

Что мне нужно изменить в map() ?

Ответ №1:

В этом случае сопоставление не требуется, поскольку это приведет к созданию нового ненужного массива. Просто выполните итерацию по каждому элементу в массиве, а затем назначьте каждому filterLabel в качестве нового ключа для obj следующим образом:

 const obj = {};
this.filterList.forEach(s => {
  obj[s.filterLabel] = s.selectedOption;
});

console.log(obj);
 

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

1. это действительно выводит именно то, что мне нужно…. Я действительно думал, что по какой-то причине мне пришлось использовать Map()… Спасибо

2. const — плохая идея в этом случае! используйте var или let

3. @i-HmD что вы предлагаете?

4. const не будет ограничивать добавление нового ключа к объекту: P

5. @AJ989 пусть или вар

Ответ №2:

Я думаю, что это вариант использования для уменьшения массива:

 let result =
[{filterLabel: 'label1', selectedOption: 'option1'}, {filterLabel: 'label2', selectedOption: 'option2'}, {filterLabel: 'label3', selectedOption: 'option3'}, {filterLabel: 'label4', selectedOption: 'option4'} ]
.reduce(function(previousValue, currentValue, index, array) {
  return { 
    [currentValue.filterLabel]: currentValue.selectedOption,
    ...previousValue }
}, {});
console.log(result); 

Подробнее: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Ответ №3:

Вы не должны ничего делать, чтобы получить желаемый результат. Во-первых, когда вы запускаете сопоставление с массивом, возвращается новый массив. Чтобы изменить это, вам придется переписать функцию map своей собственной. Технически возможно, но не рекомендуется.

Во-вторых, у вас не может быть нескольких свойств объекта с одинаковым именем. Я не знаю способа обойти это.

Возможно, вы сможете сделать что-то вроде того, что хотите, с помощью цикла:

 let rawValues = {};
for (i = 0; i < filterList.length; i  ) { 
  rawValues[`${filterList[i].filterLabel}${i}`] =  filterList[i].selectedOption;
}
 

Что должно дать вам что-то вроде этого:

 {
   filterLabel1: selectedOption,
   filterLabel2: selectedOption,
   filterLabel3: selectedOption
}
 

Можете ли вы гарантировать, что filterLabel всегда будет уникальным?

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

1. вы, вероятно, пропустили некоторые детали, прежде всего, я указал, что имя объекта будет УНИКАЛЬНЫМ, я использовал то же самое только для примера

2. приведенный ниже пользователь предложил рабочее решение, аналогичное вашему, все дело в использовании ForEach вместо этого!

3. Мой плохой; Я пропустил уникальный отказ от ответственности. Я застрял на недопустимом объекте. Цикл For должен делать то, что вам нужно.

Ответ №4:

 var result = {};
this.filterList.forEach(s => {
  result[s.filterLabel] = s.selectedOption;
});
 

вы можете использовать reduce для достижения того же результата:

 var result = this.filterList.reduce((prev, next) => {
  return {...prev, [next.filterLabel]:next.selectedOption}
}, {});