Javascript - 减少和数组
Javascript - Reduce and Array
我试图通过他们的 ID 找到获取唯一记录,包括带有最下方代码的名称,如果我将 if
语句替换为:
if (p.indexOf(c.ID) < 0) p.push(c.ID);
它将创建一个具有唯一 ID 的数组,但我希望我的最终数组也有人名,所以我修改了 if 语句,但是 p[1] 没有第一次初始化并且 reduce 函数没有't 运行 正如预期的那样。如何正确更改下面的代码以实现我想要的效果?
var arrayUnique = function(a) {
return a.reduce(function(p, c) {
if (p[1].indexOf(c.ID) < 0) p.push([c.person, c.ID]);
return p;
}, []);
};
你在这里弄乱了数据结构。如果您将一个数组压入另一个数组,indexOf
将不会像您预期的那样工作。相反,推动对象。
var arrayUnique = function(a) {
return a.reduce(function(p, c) {
if (!p['i' + c.ID]) p['i' + c.ID] = {name: c.person, id: c.ID};
return p;
}, {});
};
if(!p['i' + c.ID])
所做的是,它检查是否已经有一个 属性 该名称。原因是,将其与字符串 'i'
连接起来是为了使其成为 identifier.
console.log(arrayUnique([
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'Ian' },
{ ID: 2, person: 'Jenny' }
]));
/*
{
i1: {id: 1, name: 'John'},
i2: {id: 2, name: 'Malcolm'},
i3: {id: 3, name: 'Vera'}
}
*/
表达式p[1]
不是数组p
中所有id:s的数组,它是数组p
中的第二项。
您将使用 findIndex
方法,以便您可以提供一个函数来比较项目中的 id:s:
function arrayUnique(a) {
return a.reduce(function(p, c) {
if (p.findIndex(function(e){ return e[1] == c.ID; }) == -1) p.push([c.person, c.ID]);
return p;
}, []);
}
console.log(arrayUnique([
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'Ian' },
{ ID: 2, person: 'Jenny' }
]));
注意:并非所有浏览器都支持 findIndex
方法,因此您需要 'polyfill' 来支持它们。您可以在 findIndex
documentation.
中找到一个
也可以使用具有更广泛支持的 filter
method 来完成,但会产生更多开销:
function arrayUnique(a) {
return a.reduce(function(p, c) {
if (p.filter(function(e){ return e[1] == c.ID; }).length == 0) p.push([c.person, c.ID]);
return p;
}, []);
}
具有临时对象和哈希函数的解决方案。
var array = [
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' }
],
unique = array.reduce(function (r, a) {
if (!(a.ID in r.hash)) {
r.array.push(a);
r.hash[a.ID] = true;
}
return r;
}, { array: [], hash: [] }).array;
document.write('<pre>' + JSON.stringify(unique, 0, 4) + '</pre>');
我试图通过他们的 ID 找到获取唯一记录,包括带有最下方代码的名称,如果我将 if
语句替换为:
if (p.indexOf(c.ID) < 0) p.push(c.ID);
它将创建一个具有唯一 ID 的数组,但我希望我的最终数组也有人名,所以我修改了 if 语句,但是 p[1] 没有第一次初始化并且 reduce 函数没有't 运行 正如预期的那样。如何正确更改下面的代码以实现我想要的效果?
var arrayUnique = function(a) {
return a.reduce(function(p, c) {
if (p[1].indexOf(c.ID) < 0) p.push([c.person, c.ID]);
return p;
}, []);
};
你在这里弄乱了数据结构。如果您将一个数组压入另一个数组,indexOf
将不会像您预期的那样工作。相反,推动对象。
var arrayUnique = function(a) {
return a.reduce(function(p, c) {
if (!p['i' + c.ID]) p['i' + c.ID] = {name: c.person, id: c.ID};
return p;
}, {});
};
if(!p['i' + c.ID])
所做的是,它检查是否已经有一个 属性 该名称。原因是,将其与字符串 'i'
连接起来是为了使其成为 identifier.
console.log(arrayUnique([
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'Ian' },
{ ID: 2, person: 'Jenny' }
]));
/*
{
i1: {id: 1, name: 'John'},
i2: {id: 2, name: 'Malcolm'},
i3: {id: 3, name: 'Vera'}
}
*/
表达式p[1]
不是数组p
中所有id:s的数组,它是数组p
中的第二项。
您将使用 findIndex
方法,以便您可以提供一个函数来比较项目中的 id:s:
function arrayUnique(a) {
return a.reduce(function(p, c) {
if (p.findIndex(function(e){ return e[1] == c.ID; }) == -1) p.push([c.person, c.ID]);
return p;
}, []);
}
console.log(arrayUnique([
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'Ian' },
{ ID: 2, person: 'Jenny' }
]));
注意:并非所有浏览器都支持 findIndex
方法,因此您需要 'polyfill' 来支持它们。您可以在 findIndex
documentation.
也可以使用具有更广泛支持的 filter
method 来完成,但会产生更多开销:
function arrayUnique(a) {
return a.reduce(function(p, c) {
if (p.filter(function(e){ return e[1] == c.ID; }).length == 0) p.push([c.person, c.ID]);
return p;
}, []);
}
具有临时对象和哈希函数的解决方案。
var array = [
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' },
{ ID: 3, person: 'Vera' },
{ ID: 1, person: 'John' },
{ ID: 2, person: 'Malcolm' }
],
unique = array.reduce(function (r, a) {
if (!(a.ID in r.hash)) {
r.array.push(a);
r.hash[a.ID] = true;
}
return r;
}, { array: [], hash: [] }).array;
document.write('<pre>' + JSON.stringify(unique, 0, 4) + '</pre>');