Javascript - Reduce和Array

时间:2016-01-09 14:38:37

标签: javascript arrays reduce

我正在尝试通过其ID找到获取唯一记录,包括下面代码最多的名称以及我是否将if语句替换为:

if (p.indexOf(c.ID) < 0) p.push(c.ID);

它将创建一个具有唯一ID的数组,但我希望我的最终数组也有人名,所以我修改了if语句,但是第一次没有初始化p [1]而reduce函数没有按预期运行。如何正确更改下面的代码以满足我的需求?

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;
    }, []);
};

3 个答案:

答案 0 :(得分:2)

你在搞乱数据结构。如果您将数组推入数组,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'后面的原因是使其成为标识符

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'}
   }
*/

答案 1 :(得分:2)

表达式p[1]不是数组p中所有id:s的数组,它是数组p中的第二项。< / p>

您可以使用findIndex方法,以便提供一个比较项目中id:s的函数:

&#13;
&#13;
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' }
]));
&#13;
&#13;
&#13;

注意:并非所有浏览器都支持findIndex方法,因此您需要使用&#39; polyfill&#39;支持他们。您可以在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;
  }, []);
}

答案 2 :(得分:2)

具有临时对象和散列函数的解决方案。

&#13;
&#13;
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>');
&#13;
&#13;
&#13;