Как я могу достичь того же результата без использования метода массива map ()? В чем именно заключается значение использования метода массива map() здесь?

#javascript #arrays #function #methods #javascript-objects

Вопрос:

Исходный контент можно найти здесь: https://github.com/LinkedInLearning/javascript-essential-training-2832077/tree/main/08_17. Код, о котором идет речь, находится в этом блоке прямо здесь:

 import backpackObjectArray from "./components/data.js";

const content = backpackObjectArray.map((backpack)=>{

  let backpackArticle = document.createElement("article");
  backpackArticle.classList.add("backpack");

  // Set article ID to the backpack.id property
  backpackArticle.setAttribute("id", backpack.id);

  backpackArticle.innerHTML=`
  <figure class="backpack__image">
    <img src=${backpack.image} alt="" />
  </figure>
  <h1 class="backpack__name">${backpack.name}</h1>
  <ul class="backpack__features">
    <li class="packprop backpack__volume">Volume:<span> ${
      backpack.volume
    }l</span></li>
    <li class="packprop backpack__color">Color:<span> ${
      backpack.color
    }</span></li>
    <li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
    <li class="packprop backpack__pockets">Number of pockets:<span> ${
      backpack.pocketNum
    }</span></li>
    <li class="packprop backpack__strap">Left strap length:<span> ${
      backpack.strapLength.left
    } inches</span></li>
    <li class="packprop backpack__strap">Right strap length:<span> ${
      backpack.strapLength.right
    } inches</span></li>
    <li class="feature backpack__lid">Lid status:<span> ${
      backpack.lidOpen ? "open" : "closed"
    }</span></li>
  </ul>
  `;
  return backpackArticle;
})



const main = document.querySelector(".maincontent");

content.forEach((backpack)=>{
  main.append(backpack);
}
)
 

В сущности, можно ли просто использовать цикл forEach для вывода того же результата, что и при использовании метода массива map (), который заключается в выводе HTML-статьи для каждого объекта?

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

1. Да, это возможно, но громоздко, почему бы вам не предпочесть forEach map ?

Ответ №1:

Вы определенно можете использовать цикл forEach, если захотите, просто код будет немного другим. Использование карты не обязательно, если вам нравится, как выглядит новый код.

 import backpackObjectArray from "./components/data.js";

const main = document.querySelector(".maincontent");

backpackObjectArray.forEach((backpack) => {
  let backpackArticle = document.createElement("article");
  backpackArticle.classList.add("backpack");

  // Set article ID to the backpack.id property
  backpackArticle.setAttribute("id", backpack.id);

  backpackArticle.innerHTML = `
    <figure class="backpack__image">
      <img src=${backpack.image} alt="" />
    </figure>
    <h1 class="backpack__name">${backpack.name}</h1>
    <ul class="backpack__features">
      <li class="packprop backpack__volume">Volume:<span> ${
        backpack.volume
      }l</span></li>
      <li class="packprop backpack__color">Color:<span> ${
        backpack.color
      }</span></li>
      <li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
      <li class="packprop backpack__pockets">Number of pockets:<span> ${
        backpack.pocketNum
      }</span></li>
      <li class="packprop backpack__strap">Left strap length:<span> ${
        backpack.strapLength.left
      } inches</span></li>
      <li class="packprop backpack__strap">Right strap length:<span> ${
        backpack.strapLength.right
      } inches</span></li>
      <li class="feature backpack__lid">Lid status:<span> ${
        backpack.lidOpen ? "open" : "closed"
      }</span></li>
    </ul>
    `;

  main.append(backpackArticle);
});

 

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

1. Спасибо вам за пример! Однако теперь мне любопытно, почему большинство людей говорят, что простое использование forEach приводит к большему количеству кода, когда мне кажется, что это не так

2. Не знаю, почему они так говорят, лол. Очевидно, что это не так.

Ответ №2:

*Pseudo-code* Array.prototype.map(function(ea){return backpackArticle}) просто создаст новый массив и будет включать все, что вы возвращаете в каждой итерации.

Вы можете достичь того же самого другими способами, но, как уже было сказано, с помощью большего количества кода. На самом деле «значимость» в данном случае заключается в том, чтобы просто достичь желаемого результата с меньшим количеством кода.

Я думаю, что в вашем примере это означает явное создание нового массива, а затем явное добавление каждого backpackArticle из них к <main> использованию forEach. Вы можете пропустить создание нового массива с помощью карты.

Ответ №3:

Редактировать

Извините, я, кажется, недостаточно внимательно прочитал ваш вопрос. В вашем случае, да, вы можете обмениваться .map .forEach созданными элементами и добавлять их напрямую, не сохраняя их в промежуточном массиве.

Впрочем, остальное я оставлю как есть, может быть, кому-то это покажется полезным.


В качестве несколько общего ответа: «Да, вы могли бы использовать .forEach и получить те же результаты». И вы также можете сделать это с .reduce помощью . Однако, если вы хотите получить список результатов из списка источников (как в вашем примере), .map это правильный путь.

Я собираюсь ответить на ваш вопрос в более общем плане, потому что мне кажется, что вы спрашиваете о разнице между .forEach и .map в целом.

Каждый метод Array.prototype существует с определенной целью. Цель .map состоит в том, чтобы спроецировать (или «сопоставить», отсюда и название) функцию на все элементы списка. Поэтому, если вы хотите перейти от списка значений к списку других значений, вы можете использовать .map .

 const sources = [1, 2, 3, 4, 5];
const results = sources.map(n => n   1);
console.log(results); // logs [2, 3, 4, 5, 6]
 

Чтобы получить то же .forEach самое , у вас будет такое же количество переменных, но вам нужно будет запрограммировать еще два шага: один для создания results массива, другой для добавления в него элементов вручную.

 const sources = [1, 2, 3, 4, 5];
const results = [];
sources.forEach(n => {
  results.push(n);
});
console.log(results);
 

Путем прямого сравнения вы можете легко увидеть, что использование .forEach результатов дает немного больше кода, который менее декларативен и более императивен по стилю.

Как упоминалось ранее, вы также можете использовать .reduce для сопоставления функции со значением и накапливать его в результирующий список. На самом деле, с помощью этого можно записать огромное количество операций .reduce . Если вам интересно, поищите transducers , есть несколько доступных библиотек на разных языках.

Но вернемся к примеру с использованием reduce :

 const sources = [1, 2, 3, 4, 5];
const results = sources.reduce((acc, n) => acc.concat(n   1), []);
console.log(results); // logs [2, 3, 4, 5, 6]