将JavaScript数组减少为与计数匹配的元素

时间:2014-09-14 03:05:22

标签: javascript arrays

假设我有一个嵌套数组:

// 3rd element in sub-array indicates a number of repeats
var list = [["a","b",1],["a","d",1],["a","b",1],["c","d",1]]; 

任务是删除相同的子数组并增加单个唯一子数组中的数字,这将指示重复的次数,因此上面的示例将转换为smth,如:

[["a","b",2],["a","d",1],["c","d",1]]

实现这一目标的最有效方法是什么?

目前我正在尝试这样的事情:

var list = new Array();

// Sort by second element
list.sort(function(a,b) {
        return a[1] > b[1];
});

function collateList(element,index,array){
    // if 1st&2nd element of subarray equals to 1st&2nd element of next subarray
    if (array[index[0]]==array[index[0]+1] && array[index[1]]==array[index[1]+1]){
        // increase 3rd element of subarray by 1
        array[index[2]] = array[index[2]+1];
        // remove next element from an array
        array.splice((index+1),1);
    } 
}

list.forEach(collateList);

1 个答案:

答案 0 :(得分:0)

让我们首先定义确定是否要组合两个子数组的函数,在这种情况下,它们的前两个值是相同的:

function match(e1, e2) { return e1[0]===e2[0] && e1[1]===e2[1]; }

现在让我们定义一个函数,该函数根据匹配函数在数组中查找匹配元素,并返回其索引。如果已定义,则与Array.prototype.findIndex相同。

function find(a, v, fn) {
    for (i in a) { if (fn(v, a[i])) {return i;} }
    return -1;
}

现在我们通过reduce提供输入来创建一个新数组,其中更新了计数并删除了重复项:

list.reduce(                                  // Boil down array into a result
    function(result, elt) {                   // by taking each element
        var prev = find(result, elt, match);  // and looking for it in result so far.
        if (prev !== -1) {                    // If found
            result[prev][2]++;                // increment previous occurrence;
        } else {                              // otherwise
            result.push(elt);                 // include as is in the result.
        }
        return result;                        // Use this result for next iteration.
    }, 
    []                                        // Start off with an empty array.
)