通过合并具有相同字段值的元素来获取对象数组的唯一元素

Get unique elements of an abject array by merging elements with same value of field

有一个包含一些 object 的数组,其中可以包含具有相同标题(和不同类型)的元素。 应合并这些元素以获得具有唯一标题的结果数组,但个人信息 object 不应丢失。

所以这个...

array = [
    { id: 1, title: 'one', type: 'infos' },
    { id: 2, title: 'two', type: 'infos' },
    { id: 3, title: 'same', type: 'infos' },   // <--
    { id: 1, title: 'oneDiff', type: 'article' },
    { id: 2, title: 'same', type: 'article' },
    { id: 3, title: 'three', type: 'article' } // <--
]

...应该得到:

distinct = [
    { id: 1, title: 'one', type: 'infos' },
    { id: 2, title: 'two', type: 'infos' },
    { id: 1, title: 'oneDiff', type: 'article' },
    { id: 3, title: 'three', type: 'article' },
    { id: [{ id: 3, type: 'infos'}, { id: 2, type: 'article'}], title: 'same', type: 'multiple' }
]

我试着从这个开始,但我没能得到我需要的结果:

var unique = {};
var distinct = [];
for( var i in array ){
    if( typeof(unique[array[i].title]) == "undefined"){
        distinct.push(array[i].title);
    }
    unique[array[i].title] = 0;
}

我有一个快速的想法。 为什么不将标题和类型连接在一起,并将它们放在一个数组中? 所以如果你有

title: 'apple'
type: 'golden'

然后你将它们与下划线连接在一起得到

apple_golden

当然,这只有在您在任何标题或类型中没有下划线时才有效。如果这样做,您可以创建一个独特的字符组合来表示新单词的开头。

例如:

apple!-!-!golden

我试着用 array.reduce 来做。所以如果你不支持ie8你可以使用它。一个注意事项:没有额外的数组我做不到。

var tempArray = [];
var result = array.reduce(function (memo, element) {
    var index = tempArray.indexOf(element.title);

    if (index === -1) {
        tempArray.push(element.title);
        memo.push(element);
    } else {
        if (typeof memo[index].id === 'number') {
            memo[index].id = [{
                id: memo[index].id,
                type: memo[index].type
            }];

            memo[index].type = 'multiple';
        }

        memo[index].id.push({
            id: element.id,
            type: element.type
        });

        tempArray.push(null);
    }

    return memo;
}, []);

Example on jsbin