Функционально неизменный способ в javascript для копирования массива с дополнительными элементами в определенных позициях в зависимости от состояния элементов

У меня есть массив:

[
    { "name": "batman", "hasSidekick": true },
    { "name": "shazam!", "hasSidekick": false },
    { "name": "capt america", "hasSidekick": true },
    { "name": "spiderman", "hasSidekick": false }
]

Исходя из этого, я хочу создать новый массив имен героев, который будет иметь все вышеперечисленные имена, но когда hasSidekick имеет значение true для героя, после него должно быть добавлено дополнительное имя.

Ожидаемый результат:

[
    "batman",
    "batman's sidekick",
    "shazam!", ,
    "capt america",
    "capt america's sidekick",
    "spiderman"
]

Я могу сделать это с помощью forEach и hasSidekick дополнительные элементы условно на основе hasSidekick :

const heroes = [
  { name: "batman", hasSidekick: true },
  { name: "shazam!", hasSidekick: false },
  { name: "capt america", hasSidekick: true },
  { name: "spiderman", hasSidekick: false },
];
let heroesAndSidekicks = [];
heroes.forEach(hero => {
  heroesAndSidekicks.push(hero.name);
  if (hero.hasSidekick) {
    heroesAndSidekicks.push(`${hero.name}'s sidekick`);
  }
});
console.log(heroesAndSidekicks);

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

Всего 2 ответа


Вы можете взять Array#flatMap .

var data = [{ name: "batman", hasSidekick: true }, { name: "shazam!", hasSidekick: false }, { name: "capt america", hasSidekick: true }, { name: "spiderman", hasSidekick: false }],
    result = data.flatMap(({ name, hasSidekick }) => hasSidekick
        ? [name, name + ''s sidekick']
        : name
    );

console.log(result);


Я думаю, что Array.prototype.reduce() может решить вашу проблему. Из документации:

Метод redu () выполняет функцию редуктора (которую вы предоставляете) для каждого элемента массива, в результате чего получается одно выходное значение.

Пожалуйста, найдите возможное решение ниже:

const data = [
    { "name": "batman", "hasSidekick": true },
    { "name": "shazam!", "hasSidekick": false },
    { "name": "capt america", "hasSidekick": true },
    { "name": "spiderman", "hasSidekick": false }
];

const result = data.reduce((a, e) => {
  a.push(e.name);

  if (e.hasSidekick) {
     a.push(`${e.name}'s sidekick`);
  }

  return a;
}, []);

console.log(result);

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


Есть идеи?

10000