将多维数组转换为单个数组(Javascript)

时间:2015-09-26 11:23:46

标签: javascript arrays object multidimensional-array

我有一个对象数组(来自XLSX.js解析器,因此它的长度和内容各不相同)代表已经给予项目的授权。

简化,它看起来像这样:

var grants = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
    { id: "p_3", location: "loc_3", type: "C", funds:  "500" },
    { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
    { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];

我需要将这些合并到一个新的数组中,如下所示:

var projects = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: ["B", "D", "E"], funds: ["2000", "1000", "3000"] },
    { id: "p_3", location: "loc_3", type: "C", funds: "500" }
];

...这样当id相同时,它会合并对象并合并其键值的某些(在示例type和{{ 1}})成一个简单的子数组。这些合并对象中的其他键(funds)继承第一个实例中的值,而忽略其余的值。

经过几次失败的尝试和大量的在线搜索后,我从this answer得到了一个想法,就像这样循环location

grants

它实际上工作得很好,除了我需要一个数组,我从末尾(从上面提到的答案)中删除var res = {}; $.each(grants, function (key, value) { if (!res[value.id]) { res[value.id] = value; } else { res[value.id].type = [res[value.id].type, value.type]; res[value.id].funds = [res[value.id].funds, value.funds]; } }); var projects = [] projects = $.map( res, function (value) { return value; } ); ,这反过来又创造了我似乎无法解决的问题现在。如果其中至少有三个项目,子数组会以某种方式嵌套在彼此中!我有点理解为什么(循环),但我想知道是否有办法将对象内的所有这些小多维数组转换为sigle数组(如:.join(','))?



type: ["B", "D", "E"]

var grants = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
    { id: "p_3", location: "loc_3", type: "C", funds:  "500" },
    { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
    { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];

var res = {};

$.each(grants, function (key, value) {
    if (!res[value.id]) {
        res[value.id] = value;    
    } else {
        res[value.id].type = [res[value.id].type, value.type];
        res[value.id].funds = [res[value.id].funds, value.funds];
    }
});

var projects = []
projects = $.map( res, function (value) { return value; } );


$("pre").html(JSON.stringify(projects,null,2));




4 个答案:

答案 0 :(得分:1)

你可以改变这些行:

 res[value.id].type = [res[value.id].type, value.type];
 res[value.id].funds = [res[value.id].funds, value.funds];

对此:

Array.isArray(res[value.id].type) ? res[value.id].type.push(value.type) : res[value.id].type = [res[value.id].type, value.type];
Array.isArray(res[value.id].funds) ? res[value.id].funds.push(value.funds) : res[value.id].funds = [res[value.id].funds, value.funds];

答案 1 :(得分:1)

我提出这个解决方案。

如果索引存在于项目数组中,它具有查找功能,如果是,则推送类型和资金,否则类型和资金属性将更改为数组,其值为第一个元素。

var grants = [
        { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
        { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
        { id: "p_3", location: "loc_3", type: "C", funds: "500" },
        { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
        { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
    ],
    project = [];

grants.forEach(function (a) {
    !project.some(function (b, i) {
        if (a.id === b.id) {
            project[i].type.push(a.type);
            project[i].funds.push(a.funds);
            return true;
        }
    }) && project.push({ id: a.id, location: a.location, type: [a.type], funds: [a.funds] });
});
document.write('<pre>' + JSON.stringify(project, 0, 4) + '</pre>');

答案 2 :(得分:1)

这会是一个想法吗?

var grants = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
    { id: "p_3", location: "loc_3", type: "C", funds:  "500" },
    { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
    { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
var joined = [];

// map and push to joined
grants.map(
  function (v) {
    if (!(v.id in this)) {
      this[v.id] = v;
      joined.push(v);
    } else {
      var current = this[v.id];
      current.type = [v.type].concat(current.type);
      current.funds = [v.funds].concat(current.funds);
    }
  }, {}
);

// show it
document.querySelector('#result').textContent =
   JSON.stringify(joined, null, ' ');
<pre id="result"></pre>

答案 3 :(得分:1)

这样做:

var tempArr = [];
var result  = [];
for(i in grants){
  var rowObj = grants[i];
  var idPos  = tempArr.indexOf(rowObj.id);
  if(idPos > -1){
     result[idPos].type.push(rowObj.type);
     result[idPos].funds.push(rowObj.funds);
  }else{
    tempArr.push(rowObj.id);
    rowObj.type  = [rowObj.type]
    rowObj.funds = [rowObj.funds]
    result.push(rowObj);
  }
}
console.log(result);