Я хотел бы отфильтровать массив элементов с помощью функции map()
. Вот фрагмент кода:
var filteredItems = items.map(function(item)
{
if( ...some condition... )
{
return item;
}
});
Проблема в том, что отфильтрованные элементы все еще занимают место в массиве, и я хотел бы полностью их удалить.
Есть идеи?
EDIT: Спасибо, я забыл о filter()
, то, что я хотел, на самом деле filter()
, а затем map()
.
EDIT2: Спасибо, что указали, что map()
и filter()
реализованы не во всех браузерах, хотя мой конкретный код не был предназначен для запуска в браузере.
Вам следует использовать метод filter
, а не map, если вы не хотите изменять элементы в массиве в дополнение к фильтрации.
Например.
var filteredItems = items.filter(function(item)
{
return ...some condition...;
});
[Edit: Конечно, вы всегда можете сделать sourceArray.filter(...).map(...)
, чтобы и фильтровать, и мутировать].
Я писал ответ некоторое время назад, и мое мнение изменилось. Я рекомендую проверить мои блоге, который расширяет эту тему и объясняет гораздо лучше. Это также дает сравнение см. Этот тест jsperf в конце альтернатив.
TL;д-р это:
Для достижения того, что вы'вновь просит (фильтрация и преобразование в течение одного вызова функции), вы должны использовать массива.уменьшить()
. Однако more readable и usually faster<суп>2</суп> подход, чтобы просто использовать фильтр и карту прикованы друг к другу:
[1,2,3].фильтр(Нум => числ > 2).карте(Нум => числ * 2)
Далее следует описание того, как массив.сократить строительство ()`, и как он может быть использован для выполнения filter и map в одну итерацию. Если это слишком сокращенная, я настоятельно рекомендую посетить блог по указанной выше ссылке, который является намного более дружественным интро с наглядными примерами и прогрессии.
Вы даете уменьшить аргумент, который является функцией (обычно анонимные).
Анонимные функции принимает два параметра-один (как анонимные функции, переданного в карта/фильтр/foreach) является самой iteratee на операцию. Есть еще один аргумент для анонимная функция, переданная для того, чтобы уменьшить, что эти функции не принимают, и это значение, которые передаются между вызовами функции, часто называют памятка.
Обратите внимание, что во время выбора.фильтр() принимает только один аргумент (функция), массив.функция reduce() принимает также к важным (хотя и необязательным) второй аргумент: начальное значение 'Мемо', которые будут передаваться в эту анонимную функцию в качестве первого аргумента, и впоследствии могут быть видоизменены и передал между вызовами функции. (Если он не указан, то 'Мемо' в первую анонимную функцию вызов по умолчанию быть первым iteratee, и 'iteratee' аргумент будет второе значение в массиве)
В нашем случае, мы'МР пройти в пустой массив, чтобы начать, а затем выберите, чтобы придать нашей iteratee в наше время или не основано на наша функция-это процесс фильтрации.
Наконец, мы'МР вернуть наши 'массив в прогресс' на каждый анонимный вызов функции, и снизить примет это возвращаемое значение и передать его в качестве аргумента (так называемый памятка) до следующего вызова функции.
Это позволяет фильтр и карту произойти за одну итерацию, вырубка наше число необходимых итераций в два раза. :)
Для получения более полной информации обратитесь к МДН или по ссылке выше. :)
Простой пример сокращения назовем:
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, [])
Обратите внимание, что первая iteratee не было больше, чем одна, и так фильтруют. Также обратите внимание на 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.
Пример как написать свой собственный функция reduce (это часто помогает понять функции, такие как эти, я считаю):
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;
}
Настоящая реализация позволяет получить доступ к вещи, как индекс, например, но я надеюсь, это поможет вам сделать несложный почувствовать суть.
Это не то, что делает map. Вам действительно нужен Array.filter. Или, если вы действительно хотите удалять элементы из исходного списка, вам придется делать это императивно с помощью цикла for.
в
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 )
в
Однако следует отметить, что 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;
};
}
Сделав это, вы сможете прототипировать любой метод, который вам может понадобиться.
следующее заявление очищает объекта с помощью функции map.
var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);