当前位置:  开发笔记 > 编程语言 > 正文

在JavaScript中使用Array.map删除元素

如何解决《在JavaScript中使用Array.map删除元素》经验,为你挑选了4个好方法。

我想通过使用该map()函数来过滤项目数组.这是一段代码:

var filteredItems = items.map(function(item)
{
    if( ...some condition... )
    {
        return item;
    }
});

问题是过滤掉的项目仍然使用数组中的空间,我想完全消除它们.

任何的想法?

编辑:谢谢,我忘了filter(),我想要的实际上是filter()一个map().

EDIT2:感谢您指出map()并且filter()并未在所有浏览器中实现,尽管我的特定代码并不打算在浏览器中运行.



1> olliej..:

filter除了过滤之外,您应该使用方法而不是map,除非您想要改变数组中的项目.

例如.

var filteredItems = items.filter(function(item)
{
    return ...some condition...;
});

[编辑:当然你总是可以做sourceArray.filter(...).map(...)过滤和变异]


但是你可以在`map`中变异.
`map`不变异

2> Kyle Baker..:

我现在回答了一段时间,我的意见发生了变化.我建议查看我的博客文章,它扩展了这个主题并更好地解释了它.它还在替代方案的最后给出了JSperf比较.

tl; dr就是这样:要完成你所要求的(在一个函数调用中过滤和映射),你应该使用Array.reduce().然而,更可读 通常更快的2方法是仅使用链接和映射链接在一起:

[1,2,3].filter(num => num > 2).map(num => num * 2)

以下是对如何Array.reduce()工作的描述,以及如何在一次迭代中使用它来完成过滤和映射.如果这太过浓缩,我强烈建议您查看上面链接的博客文章,这是一个更加友好的介绍,有清晰的示例和进展.

你给减少一个(通常是匿名的)函数的参数.

该匿名函数有两个参数 - 一个(如传入map/filter/forEach的匿名函数)是要操作的iteratee.然而,传递给reduce的匿名函数有另一个参数,即那些函数不接受,这是函数调用之间传递的值,通常称为备忘录.

请注意,虽然Array.filter()只接受一个参数(一个函数),但Array.reduce()也接受一个重要的(尽管是可选的)第二个参数:'memo'的初始值,它将作为其传递给该匿名函数第一个参数,随后可以在函数调用之间进行变异和传递.(如果没有提供,那么第一个匿名函数调用中的'memo'将默认为第一个iteratee,'iteratee'参数实际上将是数组中的第二个值)

在我们的例子中,我们将传入一个空数组来启动,然后根据我们的函数选择是否将我们的iteratee注入到我们的数组中 - 这是过滤过程.

最后,我们将在每个匿名函数调用中返回'正在进行的数组',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, [])

请注意,第一个iteratee不大于1,因此被过滤.还要注意initialMemo,命名只是为了使其存在清晰并引起对它的注意.再一次,它作为'memo'传递给第一个匿名函数调用,然后匿名函数的返回值作为'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;
}

例如,真正的实现允许访问索引之类的东西,但我希望这可以帮助您获得简单的感觉.


辉煌!我多年来一直想做这样的事情。决定尝试找出一种不错的方式,哇,自然的JavaScript!

3> Patrick..:

这不是地图的作用.你真的想要Array.filter.或者如果你真的想从原始列表中删除元素,那么你需要使用for循环来强制执行它.



4> vsync..:
数组过滤方法

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 )
推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有