Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中使用Array.map删除元素_Javascript_Functional Programming_Data Manipulation_Client Side - Fatal编程技术网

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

在JavaScript中使用Array.map删除元素,javascript,functional-programming,data-manipulation,client-side,Javascript,Functional Programming,Data Manipulation,Client Side,我想使用map()函数过滤项目数组。以下是一段代码片段: var filteredItems = items.map(function(item) { if( ...some condition... ) { return item; } }); 问题是,过滤掉的项目仍然会占用数组中的空间,我想完全清除它们 有什么想法吗 编辑:谢谢,我忘记了filter(),我想要的实际上是一个filter()然后是一个map() EDIT2:感谢您指出并非所有浏览器都

我想使用
map()
函数过滤项目数组。以下是一段代码片段:

var filteredItems = items.map(function(item)
{
    if( ...some condition... )
    {
        return item;
    }
});
问题是,过滤掉的项目仍然会占用数组中的空间,我想完全清除它们

有什么想法吗

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


EDIT2:感谢您指出并非所有浏览器都实现了
map()
filter()。你真的想要。或者,如果您确实想从原始列表中删除元素,则需要使用for循环强制执行此操作。

您应该使用
filter
方法,而不是map方法,除非您想在过滤之外对数组中的项进行变异

例如


[编辑:当然,您可以始终执行
sourceArray.filter(…).map(…)
以同时进行筛选和变异]

您必须注意的是,并非所有浏览器都支持
数组.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;
    };
}
<代码> //这个原型是由Mozilla基金会提供的。 //是根据麻省理工学院许可证发行的。 //http://www.ibiblio.org/pub/Linux/LICENSES/mit.license if(!Array.prototype.filter) { Array.prototype.filter=函数(fun/*,thisp*/) { var len=此长度; 如果(乐趣的类型!=“功能”) 抛出新的TypeError(); var res=新数组(); var thisp=参数[1]; 对于(变量i=0;i
这样,您就可以创建您可能需要的任何方法的原型

排列
var-arr=[1,2,3]
//ES5语法
arr=arr.filter(函数(项){返回项!=3})
//ES2015语法
arr=arr.filter(项=>项!=3)

console.log(arr)
受写这个答案的启发,我后来扩展并写了一篇博客文章,详细讨论了这个问题。如果您想更深入地理解如何思考这个问题,我建议您——我试着一点一点地解释它,并在最后给出一个JSperf比较,讨论速度方面的考虑

也就是说,**tl;dr是这样的:

要实现您的要求(在一个函数调用中进行过滤和映射),可以使用
Array.reduce()
**。 然而,更具可读性的(不太重要)通常更快的方法是只使用链接在一起的过滤器和映射:
[1,2,3]。过滤器(num=>num>2)。映射(num=>num*2)

下面介绍了
Array.reduce()
的工作原理,以及如何使用它在一次迭代中完成过滤和映射。再一次,如果这篇文章过于浓缩,我强烈建议你看看上面的链接,这是一篇更加友好的介绍,有着清晰的例子和进展


您给出的reduce参数是一个(通常是匿名)函数

var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);
这个匿名函数有两个参数——一个(就像传递给map/filter/forEach的匿名函数一样)是要操作的迭代器对象。但是,传递匿名函数的另一个参数是,这些函数不接受,即在函数调用之间传递的值,通常称为memo

请注意,虽然Array.filter()只接受一个参数(一个函数),Array.reduce()还接受一个重要的(尽管是可选的)第二个参数:“memo”的初始值将作为其第一个参数传递到匿名函数中,随后可以在函数调用之间进行变异和传递。(如果未提供,则默认情况下,第一个匿名函数调用中的'memo'将是第一个iteratee,而'iteratee'参数实际上将是数组中的第二个值)

在我们的例子中,我们将传入一个空数组开始,然后根据函数选择是否将迭代者注入到数组中——这是过滤过程

最后,我们将在每次匿名函数调用时返回“array in progress”,reduce将获取该返回值并将其作为参数(称为memo)传递给下一次函数调用

这允许过滤器和映射在一次迭代中发生,将我们所需的迭代次数减少了一半——不过每次迭代只需做两倍的工作,因此除了函数调用之外,没有什么真正节省了,函数调用在javascript中并不昂贵

有关更完整的解释,请参阅文档(或本答案开头引用的我的帖子)

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,因此被过滤。还要注意名字的首字母memo,它的名字只是为了清楚地表明它的存在并引起人们的注意。再次,它作为'memo'传递给第一个匿名函数调用,然后匿名函数的返回值作为'memo'参数传递给下一个函数

var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);
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=[];
//我们接受匿名函数和可选的“初始备注”值。
test\u arr.my\u reducer=函数(reduceFunc,initialMemo){
//如果我们没有传入第二个参数,那么我们的第一个memo值
//将是索引0中的任何内容。(否则,它将
//这是第二个论点。)
常量initialMemorisIndexZero=arguments.leng
var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);
state.map(item => {
            if(item.id === action.item.id){   
                    return {
                        id : action.item.id,
                        name : item.name,
                        price: item.price,
                        quantity : item.quantity-1
                    }

            }else{
                return item;
            }
        }).filter(item => {
            if(item.quantity <= 0){
                return false;
            }else{
                return true;
            }
        });
  let array = [1, 2, 3, 4, 5, 6, 7, 8];
  let mapped = array
  .filter(x => {
    let computation = x / 2 + 1;
    let isIncluded = computation % 2 === 0;
    return isIncluded;
  })
  .map(x => {
    let computation = x / 2 + 1;
    return `${x} is included because ${computation} is even`
  })

  // Output: [2 is included because 2 is even, 6 is included because 4 is even]
  let array = [1, 2, 3, 4, 5, 6, 7, 8];
  let mapped = array
  .map(x => {
    let computation = x / 2 + 1;
    let isIncluded = computation % 2 === 0;
    if (isIncluded) {
      return `${x} is included because ${computation} is even`
    } else {
      return undefined
    }
  })
  .filter(x => typeof x !== "undefined")