将密钥分解为深层Javascript对象

时间:2013-05-09 07:54:34

标签: javascript

我想迭代以下数组,然后从:

进入对象
data = [
  {k: "a_b_c", v: 1},
  {k: "a_b_c", v: 2},
  {k: "a_b_c", v: 3},
  {k: "a_b_d", v: 1},
  {k: "a_b_d", v: 2},
  {k: "a_b_d", v: 3},
  {k: "a_c_a", v: 1},
  {k: "a_c_b", v: 2},
  {k: "a_d", v: 1},
  {k: "a_d", v: 2}
]

为:

result = {
  a: {
    b: {
      c: [1,2,3],
      d: [1,2,3]
    },
    c: {
      a: [1],
      b: [2]
    },
    d: [1,2]
  },
}

关于实现这一点的任何想法?

5 个答案:

答案 0 :(得分:5)

编辑:OP改变了问题中数据的呈现方式。 以下解决方案对于代码中提到的先前数据是正确的。

您提到的对象无效。没有重复的密钥。 但是,使用唯一键,这应该是实现此目的的方法:

var result = {};

data = {
  "a_b_c": 1,
  "a_b_c": 2,
  "a_b_c": 3,
  "a_b_d": 1,
  "a_b_d": 2,
  "a_b_d": 3,
  "a_c_a": 1,
  "a_c_b": 2
}


for(the_key in data)
{
    new_keys = the_key.split("_");
    result[new_keys[0]] =  result[new_keys[0]] || {};
    result[new_keys[0]][new_keys[1]] = result[new_keys[0]][new_keys[1]]|| {};
    result[new_keys[0]][new_keys[1]][new_keys[2]] = result[new_keys[0]][new_keys[1]][new_keys[2]] || [];
    result[new_keys[0]][new_keys[1]][new_keys[2]].push(data[the_key]);
}


console.log(result);

演示:http://jsfiddle.net/8ZbMt/

答案 1 :(得分:2)

这样做:

var data = [
  {k: "a_b_c", v: 1},
  {k: "a_b_c", v: 2},
  …
]

var result = {};
for (var i=0; i<data.length; i++) {
    var keys = data[i].k.split("_"),
        o = result;
    for (var j=0; j<keys.length-1; j++)
        o = o[keys[j]] || (o[keys[j]] = {});
    o = o[keys[j]] || (o[keys[j]] = []);
    o.push(data[i].v);
}

答案 2 :(得分:1)

您所描述的是一个名为Trie,Digital Search Tree或Retrieval Tree的数据结构。

这是一个wikipedia article on tries,它包含用于构建它们的通用算法。

答案 3 :(得分:1)

这是一些可怕的代码:

var data = [
  {k: "a_b_c", v: 1},
  {k: "a_b_c", v: 2},
  {k: "a_b_c", v: 3},
  {k: "a_b_d", v: 1},
  {k: "a_b_d", v: 2},
  {k: "a_b_d", v: 3},
  {k: "a_c_a", v: 1},
  {k: "a_c_b", v: 2}
];

var result ={};

data.forEach(function(item) {
  var keys = item.k.split("_");
  var entryPoint = result;
  var l = keys.length-1;
  keys.forEach(function(key, index) {
    if (!entryPoint[key])
      entryPoint[key] = (index == l) ? [] : {};
    entryPoint = entryPoint[key];
  });
  entryPoint.push(item.v);
});

如果您同时拥有子键和值,则会失败。 (需要更改输出格式才能修复。)

答案 4 :(得分:0)

我的条目如下:

rslt = data.reduce (function (rslt, d) {
  for (var traverse = rslt, keys = d.k.split ('_'); keys.length > 1;) {
    !traverse.hasOwnProperty (keys[0]) && (traverse[keys[0]] = {});
    traverse = traverse[keys.shift ()];
  }  

  !traverse.hasOwnProperty (keys = keys[0]) && (traverse[keys] = []);
  traverse[keys].push (d.v);
  return rslt;
}, {});