9

Как пропустить элемент в .map()?

3

Как пропустить элемент массива в методе .map?

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

Вот мой код:

var sources = images.map(function (img) {
    if(img.src.split('.').pop() === "json"){ // если расширение .json
        return null; // пропустить
    }
    else{
        return img.src;
    }
});

Однако, когда я выполняю этот код, он возвращает массив с null для пропущенных элементов:

["img.png", null, "img.png"]

Как я могу изменить свой код, чтобы просто исключать элементы с json из результатов, а не возвращать null?

5 ответ(ов)

12

Вы можете использовать метод .filter() для фильтрации элементов в массиве, а затем применить .map() для извлечения нужных значений. Вот пример:

var sources = images.filter(function(img) {
  if (img.src.split('.').pop() === "json") {
    return false; // пропустим
  }
  return true;
}).map(function(img) { return img.src; });

Если вы хотите избежать использования .filter(), что не является неразумным, так как это имеет некоторые накладные расходы, вы можете воспользоваться более универсальным методом .reduce(). В общем, .map() можно выразить через .reduce() следующим образом:

someArray.map(function(element) {
  return transform(element);
});

можно записать как:

someArray.reduce(function(result, element) {
  result.push(transform(element));
  return result;
}, []);

Таким образом, если вам нужно пропустить некоторые элементы, это можно сделать с помощью .reduce():

var sources = images.reduce(function(result, img) {
  if (img.src.split('.').pop() !== "json") {
    result.push(img.src);
  }
  return result;
}, []);

В этой версии код из .filter(), приведённый в первом примере, стал частью колбэка .reduce(). Исходный путь изображения добавляется в результирующий массив только в том случае, если операция фильтрации позволила бы его сохранить.

Обновление — Этот вопрос вызывает много интереса, и я хотел бы добавить следующее пояснение. Цель метода .map(), как концепта, заключается в преобразовании списка значений в другой список значений в соответствии с определёнными правилами. Так же как бумажная карта какой-либо страны будет выглядеть странно, если на ней не будет нескольких городов, отображение из одного списка в другой имеет смысл, только если существует взаимно однозначное соответствие значений.

Я не утверждаю, что создание нового списка из старого с исключением некоторых значений не имеет смысла. Я просто хочу прояснить, что .map() имеет одно простое намерение — создать новый массив такой же длины, как старый массив, только с элементами, образованными путём преобразования старых значений.

0

Использование forEach для фильтрации массива, как в вашем примере, возможно, но это не самый оптимальный и читаемый способ решения данной задачи. Давайте разберёмся, почему лучше использовать метод filter.

Когда вы используете forEach, вам нужно создавать дополнительный массив (filtered) и вручную добавлять в него элементы, которые удовлетворяют вашему условию. Это может привести к увеличению объема кода и снижению его читаемости. Кроме того, в случае больших массивов это может повлиять на производительность, так как вам нужно выполнять два действия: проходить по массиву и добавлять элементы в новый массив.

С другой стороны, метод filter уже встроен в массивы и делает именно то, что вам нужно, за один шаг. Он проходит через каждый элемент массива, применяет указанную функцию и возвращает новый массив с элементами, которые удовлетворяют условию. Это более лаконично, и код выглядит чище:

const arr = ['a', 'b', 'c', 'd', 'e'];
const filtered = arr.filter(x => !x.includes('b')); // ['a','c','d','e'];

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

0

Чтобы убрать все null значения из массива things, можно использовать метод reduce, как в приведённом вами примере. Ваш код корректен, вот краткий разбор:

const thingsWithoutNulls = things.reduce((acc, thing) => {
  if (thing !== null) {
    acc.push(thing);
  }
  return acc;
}, []);

Здесь мы инициализируем аккумулятор acc как пустой массив. Затем для каждого элемента thing в исходном массиве things проверяем, не равен ли он null. Если это так, добавляем его в аккумулятор. В итоге возвратим массив, который не содержит null значений.

Однако, для этой задачи также можно использовать метод filter, он более лаконичен:

const thingsWithoutNulls = things.filter(thing => thing !== null);

Этот способ более читаем и выполняет ту же задачу, возвращая новый массив без null значений.

0

Вот перевод вашего кода на русский, выполненный в стиле ответа на StackOverflow:

var sources = images.map(function (img) {
    if(img.src.split('.').pop() === "json"){ // если расширение .json
        return null; // пропускаем
    }
    else{
        return img.src; // возвращаем источник изображения
    }
}).filter(Boolean); // .filter(Boolean) удаляет все ложные значения из массива, в данном случае null.

В данном коде происходит следующее: мы перебираем массив images с помощью метода map. Проверяем, имеет ли каждый элемент расширение .json. Если да, то возвращаем null, чтобы пропустить этот элемент. В противном случае возвращаем источник изображения. Затем с помощью метода filter(Boolean) мы отфильтровываем все ложные значения, что позволяет удалить все null из результирующего массива sources.

0

В приведённом вами примере кода создаётся массив arr, который содержит различные значения, включая нули, пустую строку, undefined, false, null и NaN. Затем используется метод filter с передачей функции-конструктора Boolean. Этот метод фильтрует массив, оставляя только "истинные" значения.

Вот как это работает:

  1. Boolean — это встроенная функция, которая преобразует переданное ей значение в булевый тип. В JavaScript значения, которые считаются ложными (falsy), это: 0, "" (пустая строка), undefined, null, false и NaN.
  2. Когда мы передаём Boolean в filter, массив проходит по каждому элементу и оставляет только те, которые имеют истинное (truthy) значение.

В результате вызова arr.filter(Boolean) мы получаем новый массив, который содержит только истинные значения из исходного массива:

const arr = [0, 1, '', undefined, false, 2, undefined, null, , 3, NaN];
const filtered = arr.filter(Boolean); // [ 1, 2, 3 ]
console.log(filtered);

Вывод на консоль будет: [1, 2, 3]. Таким образом, элементы 0, '', undefined, false, null и NaN были исключены из конечного массива.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь