首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript将三个二维数组组合在一起,保持第一个值的唯一性

JavaScript将三个二维数组组合在一起,保持第一个值的唯一性
EN

Stack Overflow用户
提问于 2014-05-28 13:42:46
回答 3查看 61关注 0票数 1

我有三个2D数组,其中每个2D数组中每个子数组中的第一个值是该数组的唯一值。但是,其中一些数组可能缺少值。

示例:

代码语言:javascript
复制
var a = [[1, 10], [2, 20], [3, 20]];
var b = [[1, 20], [2, 10]];
var c = [[2, 30]];

数组a的值为1、2和3,但数组b的值仅为1和2,数组c的值仅为2。

我想将这三个数组组合成一个新的最终数组,比如d。数组d应该只包含每个第一个值中的一个,因此,例如,上面的三个数组将组合成一个。

代码语言:javascript
复制
d = [[1, 10, 20], [2, 20, 10, 30], [3, 20]];

我的第一次半身尝试:

我可以用concat将这三个数组组合成一个

代码语言:javascript
复制
a = a.concat(b, c);
// a = [[1, 10], [2, 20], [3, 20], [1, 20], [2, 10], [2, 30]];

但我不知道如何把非独特的元素结合起来。我已经研究了underscore的一些功能,但我找不到真正有用的函数(尽管我是非常的新手)。

我的第二次尝试:

代码语言:javascript
复制
// First combine just a and b
for(var ai = 0; ai < a.length; ai++) {
  var inserted = false;
  for(var bi = 0; bi < b.length; bi++) {
    if(a[ai][0] == b[bi][0]) {
      d.push([(a[ai][0]), (a[ai][1]), (b[bi][1])]);
      inserted = true;
    }
  }
  if(!inserted) {
    d.push([(a[ai][0]), (a[ai][1])]);
  }
}
// Then repeat the above with d and c

这个解决方案的问题是,如果a的元素比b少,结果将不包括a没有的b元素。我可以编写一系列可笑的循环,但这将是可悲的低效率,发出这么多的JSON调用已经对网站的速度造成了影响。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-28 14:09:54

您可以尝试以下代码:

代码语言:javascript
复制
var a = [[1, 10], [2, 20], [3, 20]];
var b = [[1, 20], [2, 10]];
var c = [[2, 30]];

var d = a.concat(b,c);
var e = [];
//loop through all the inner arrays
//the first item in each array is considered as key
//the second is considered as value and should be pushed into some array 
//which can be accessed via the key.
for(var i = 0; i < d.length; i++){    
  if(!e[d[i][0]]) e[d[i][0]] = [d[i][0]];    
  e[d[i][0]].push(d[i][1]);
}

d = [];
for(var i = 0; i < e.length; i++){
  if(e[i]) d.push(e[i]);
}

console.log(d);

演示。

票数 1
EN

Stack Overflow用户

发布于 2014-05-28 14:10:12

试试这个:

代码语言:javascript
复制
function concat(first, second) {
    var result = [],
        i = 0,
        j = 0,
        k = 1;

    if (second.length > first.length) {
        result = second.slice();
        first = first.slice();
    } else {
        result = first.slice();
    }

    for (i = 0; i < result.length; i++) {
        for (j = 0; j < second.length; j++) {
            if (result[i][0] === second[j][0]) {
                for (k = 1; k < second[j].length; k++) {
                    result[i].push(second[j][k]);
                }
            }
        }
    }

    return result;
}
票数 1
EN

Stack Overflow用户

发布于 2014-05-28 14:10:53

既然每个子数组中的第一个元素是唯一的,那么为什么不这样写呢:

代码语言:javascript
复制
var a = { 1: [10], 2: [20], 3: [20] };
var b = { 1: [20], 2: [10] };
var c = { 2: [30] };

实际上,让我们编写一个函数来完成这个任务:

代码语言:javascript
复制
var a = mapFrom2DArray([[1, 10], [2, 20], [3, 20]]);
var b = mapFrom2DArray([[1, 20], [2, 10]]);
var c = mapFrom2DArray([[2, 30]]);

function mapFrom2DArray(array) {
    var map = {}, length = array.length, index = 0;

    while (index < length) {
        var subarray = array[index++];
        map[subarray[0]] = subarray.slice(1);
    }

    return map;
}

现在,让我们编写一个组合器,它获取两个映射并将它们组合起来:

代码语言:javascript
复制
function combine(a, b) {
    var c = {};

    for (var k in a) c[k] = a[k];

    for (var k in b) {
        if (c.hasOwnProperty(k))
            c[k] = c[k].concat(b[k]);
        else c[k] = b[k];
    }

    return c;
}

现在,我们只需简单地reduce地图:

代码语言:javascript
复制
var d = mapToArray([a, b, c].reduce(combine));

哦,还有mapToArray的定义

代码语言:javascript
复制
function mapToArray(map) {
    var array = [];
    for (var k in map) array.push([parseInt(k)].concat(map[k]));
    return array;
}

就这样。参见演示:http://jsfiddle.net/56B6T/1

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23913354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档