Удаление элементов с помощью Array.map в JavaScript
63209 просмотра
6 ответа
Я хотел бы отфильтровать массив элементов с помощью map()
функции. Вот фрагмент кода:
var filteredItems = items.map(function(item)
{
if( ...some condition... )
{
return item;
}
});
Проблема в том, что отфильтрованные элементы по-прежнему используют пространство в массиве, и я хотел бы полностью стереть их.
Любая идея?
РЕДАКТИРОВАТЬ: Спасибо, я забыл о том filter()
, что я хотел на самом деле filter()
тогда map()
.
РЕДАКТИРОВАТЬ 2: Спасибо за указание map()
и filter()
не реализованы во всех браузерах, хотя мой конкретный код не был предназначен для запуска в браузере.
Ответы (6)
85 плюса
Вы должны использовать filter
метод вместо отображения, если вы не хотите изменять элементы в массиве, в дополнение к фильтрации.
например.
var filteredItems = items.filter(function(item)
{
return ...some condition...;
});
[Редактировать: Конечно, вы всегда можете сделать, sourceArray.filter(...).map(...)
чтобы фильтровать и изменять]
30 плюса
Я написал ответ некоторое время назад, и мое мнение изменилось. Я рекомендую проверить мое сообщение в блоге, которое расширяет эту тему и объясняет это намного лучше. Это также дает сравнение JSperf в конце альтернатив.
Tl; dr заключается в следующем: чтобы выполнить то, что вы просите (фильтрация и отображение в пределах одного вызова функции), вы должны использоватьArray.reduce()
. Тем не менее, более удобный для чтения и обычно быстрее 2 подхода является просто использовать фильтр и карт соединен друг с другом:
[1,2,3].filter(num => num > 2).map(num => num * 2)
Далее следует описание того, как Array.reduce()
работает и как его можно использовать для выполнения фильтрации и сопоставления за одну итерацию. Если это слишком сжато, я настоятельно рекомендую посмотреть пост в блоге, связанный выше, который является гораздо более дружелюбным введением с ясными примерами и прогрессом.
Вы даете уменьшить аргумент, который является (обычно анонимной) функцией.
Эта анонимная функция принимает два параметра - один (как анонимные функции, передаваемые в map / filter / forEach) - это итератор, с которым нужно работать. Однако для анонимной функции передается еще один аргумент, заключающийся в том, что эти функции не принимаются, и это значение, которое будет передаваться между вызовами функций, часто называемое памяткой .
Обратите внимание, что в то время как Array.filter () принимает только один аргумент (функцию), Array.reduce () также принимает важный (хотя и необязательный) второй аргумент: начальное значение для memo, которое будет передано этой анонимной функции в качестве ее первый аргумент, а затем может быть видоизменен и передан между вызовами функций. (Если он не указан, то по умолчанию «memo» при первом вызове анонимной функции будет первым итератором, а аргумент «итератора» фактически будет вторым значением в массиве)
В нашем случае мы передадим пустой массив для запуска, а затем выберем, вставлять нашего итератора в наш массив или нет на основе нашей функции - это процесс фильтрации.
Наконец, мы будем возвращать наш «массив в процессе» при каждом вызове анонимной функции, а Reduce примет это возвращаемое значение и передаст его в качестве аргумента (называемого memo) следующему вызову функции.
Это позволяет фильтровать и отображать карту за одну итерацию, сокращая количество необходимых итераций вдвое. :)
Для более полного объяснения обратитесь к MDN или по ссылке выше. :)
Базовый пример вызова Reduce:
let array = [1,2,3];
const initialMemo = [];
array = array.reduce((memo, iteratee) => {
// if condition is our filter
if (iteratee > 1) {
// what happens inside the filter is the map
memo.push(iteratee * 2);
}
// this return value will be passed in as the 'memo' argument
// to the next call of this function, and this function will have
// every element passed into it at some point.
return memo;
}, initialMemo)
console.log(array) // [4,6], equivalent to [(2 * 2), (3 * 2)]
более краткая версия:
[1,2,3].reduce((memo, value) => value > 1 ? memo.concat(value * 2) : memo, [])
Обратите внимание, что первый итерируемый был не больше, чем один, и поэтому был отфильтрован. Также обратите внимание на initialMemo, названный просто, чтобы прояснить его существование и привлечь к нему внимание. Еще раз, он передается как «памятка» первому вызову анонимной функции, а затем возвращаемое значение анонимной функции передается как аргумент «записки» следующей функции.
Другим примером классического варианта использования memo будет возвращение наименьшего или наибольшего числа в массиве. Пример:
[7,4,1,99,57,2,1,100].reduce((memo, val) => memo > val ? memo : val)
// ^this would return the largest number in the list.
Пример того, как написать собственную функцию приведения (это часто помогает понять функции, подобные этим, я нахожу):
test_arr = [];
// we accept an anonymous function, and an optional 'initial memo' value.
test_arr.my_reducer = function(reduceFunc, initialMemo) {
// if we did not pass in a second argument, then our first memo value
// will be whatever is in index zero. (Otherwise, it will
// be that second argument.)
const initialMemoIsIndexZero = arguments.length < 2;
// here we use that logic to set the memo value accordingly.
let memo = initialMemoIsIndexZero ? this[0] : initialMemo;
// here we use that same boolean to decide whether the first
// value we pass in as iteratee is either the first or second
// element
const initialIteratee = initialMemoIsIndexZero ? 1 : 0;
for (var i = initialIteratee; i < this.length; i++) {
// memo is either the argument passed in above, or the
// first item in the list. initialIteratee is either the
// first item in the list, or the second item in the list.
memo = reduceFunc(memo, this[i]);
}
// after we've compressed the array into a single value,
// we return it.
return memo;
}
Реальная реализация позволяет получить доступ к таким вещам, как, например, индекс, но я надеюсь, что это поможет вам легко понять суть.
Автор: Kyle Baker Размещён: 11.04.2016 07:2511 плюса
Это не то, что делает карта. Вы действительно хотите Array.filter . Или, если вы действительно хотите удалить элементы из исходного списка, вам обязательно нужно сделать это с помощью цикла for.
Автор: Patrick Размещён: 12.08.2008 10:333 плюса
Однако вы должны заметить, что Array.filter
он поддерживается не во всех браузерах, поэтому вы должны создать прототип:
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
{
var val = this[i]; // in case fun mutates this
if (fun.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
И, делая это, вы можете создать прототип любого метода, который вам может понадобиться.
Автор: ggasp Размещён: 12.08.2008 11:443 плюса
Я размещаю этот ответ здесь, потому что полифиллы, размещенные на этой странице, ужасны
function reduce(f, y, xs, context) {
var acc = y;
for (var i = 0, len = xs.length; i < len; i++)
acc = f.call(context, acc, xs[i], i, xs);
return acc;
}
function reduce1(f, xs, context) {
if (xs.length === 0)
throw Error('cannot reduce empty array without initial value');
else
return reduce(f, xs[0], xs.slice(1), context);
}
function map(f, xs, context) {
return reduce(function(acc, x, i) {
return acc.concat([
f.call(context, x, i, xs)
]);
}, [], xs);
}
function filter(f, xs, context) {
return reduce(function(acc, x, i) {
if (f.call(context, x, i, xs))
return acc.concat([x]);
else
return acc;
}, [], xs);
}
продлить прототипы
if (Array.prototype.reduce === undefined) {
Array.prototype.reduce = function(f, initialValue, context) {
if (initialValue === undefined)
return reduce1(f, this, context);
else
return reduce(f, initialValue, this, context);
};
}
if (Array.prototype.map === undefined) {
Array.prototype.map = function(f, context) {
return map(f, this, context);
};
}
if (Array.prototype.filter === undefined) {
Array.prototype.filter = function(f, context) {
return filter(f, this, context);
};
}
Автор: user633183
Размещён: 23.09.2016 05:00
3 плюса
Метод фильтра массива
var arr = [1, 2, 3]
// ES5 syntax
arr = arr.filter(function(item){ return item != 3 })
// ES2015 syntax
arr = arr.filter(item => item != 3)
console.log( arr )
Вопросы из категории :
- javascript Как определить, какой из указанных шрифтов был использован на веб-странице?
- javascript Валидация клиентской стороны ASP.Net
- javascript Длина объекта JavaScript
- javascript Получение текста из выпадающего списка
- javascript Скрипт входа со скрытыми кнопками
- javascript Как автоматически изменить размер текстовой области с помощью Prototype?
- functional-programming Удаление элементов с помощью Array.map в JavaScript
- functional-programming В чем разница между процедурным программированием и функциональным программированием?
- functional-programming Что такое хвостовая рекурсия?
- functional-programming Что такое «Currying»?
- functional-programming Почему функциональные языки?
- functional-programming Что такое «закрытие»?
- data-manipulation Как удалить объекты из массива в Java?
- data-manipulation Как я могу получить доступ и обработать вложенные объекты, массивы или JSON?
- data-manipulation Проверить формат строки Python?
- data-manipulation Split delimited strings in a column and insert as new rows
- data-manipulation perl, удаление элементов из массива в цикле for