我有一个2D数组如下:
1230 | this is a test
1278 | my new test
1230 | test2
7654 | testing...
我想转换数组,以便第一列中的值是唯一的,第二列存储与该特定值关联的连接文本。见下面的例子。
1230 | this is a test -- test2
1278 | my new test
7654 | testing...
我知道我应该首先按照第一列对数组进行排序,然后进行合并。
以下是按第一列排序数组的代码:
var x = exp_arr.sort(function(a,b){ return a[0] > b[0] ? 1 : -1; });
alert(x);
我对如何进行合并感到有点迷茫。非常欢迎您的建议
答案 0 :(得分:4)
您可以使用reduce
命令,如下所示:
var array = [[1230, "this is a test"], [1278, "my new test"], [1230, "test2"], [7654, "testing..."]];
var result =
array.reduce(function(ob, ar) {
if (!(ar[0] in ob.nums)) {
ob.nums[ar[0]] = ar
ob.result.push(ar);
} else
ob.nums[ar[0]][1] = (ob.nums[ar[0]][1]) + " -- " + ar[1];
return ob
}, {nums:{}, result:[]}).result
.sort(function(a,b) {
return a[0] - b[0];
});
答案 1 :(得分:1)
你可以这样做:
var x = exp_arr.sort(function(a,b){ return a[0] > b[0] ? 1 : -1; }).filter((function() {
var prev = [null];
return function(item) {
if(prev[0] === item[0]) {
prev[1] += ' -- ' + item[1];
return false;
}
prev = item;
return true;
};
}()));
<强>解释强>
过滤器函数利用了数组已经排序的事实。因此,每个元素都与前一个元素进行比较(因此,闭包用于保存前一个元素)。如果前一个元素具有相同的id,我们将该字符串追加到前一个元素。
答案 2 :(得分:1)
第一组数组元素具有相同的第一个值到对象中,其键是第一个元素,值是第二个元素的数组:
groups = array.reduce(function(result, elt) {
result[elt[0]] = (result[elt[0]] || []).concat(elt[1]);
return result;
});
然后通过将每个键的数组成员与--
连接,将对象映射回数组。
Object.keys(groups).map(function(key) { return [key, groups[key].join(' -- '); })
或者,从@friedi的书中拿出一片叶子,利用先排序数组,但使用reduce
代替filter
,这稍微简单一点,因为这意味着我们不需要IIFE关闭上一个项目:
array.sort(sortfunc).reduce(result, item) {
var prev = result[result.length-1] || [];
if (prev[0] === item[0]) {
prev[1] += " -- " + item[1];
} else {
result.push(item);
}
}, []);
要么比可接受的解决方案更具可读性。