来自给定JSON数组的嵌套JSON对象数组

时间:2016-09-26 04:17:23

标签: javascript

我有一个

形式的JSON数组
[{'from':'a','to':'b','type':'add','value':'100','op':'cr'},
{'from':'a','to':'b','type':'add','value':'200','op':'dr'},
{'from':'a','to':'b','type':'add','value':'300','op':'cr'},
{'from':'c','to':'d','type':'sub','value':'400','op':'dr'},
{'from':'c','to':'d','type':'sub','value':'500','op':'cr'}]

我希望输出为

[{'from':'a','to':'b','add':[{'100':'cr'},{'200':'dr'},{'300':'cr'}]},
 {'from':'c','to':'d','sub':[{'400':'dr'},{'500':'cr'}]}]

如何在Javascript / NodeJS中执行此操作?

3 个答案:

答案 0 :(得分:2)

以下代码块具有resample功能,可以解决您的任务。

var sampleData = [
  {'from':'a','to':'b','type':'add','value':'100','op':'cr'},
  {'from':'a','to':'b','type':'add','value':'200','op':'dr'},
  {'from':'a','to':'b','type':'add','value':'300','op':'cr'},
  {'from':'c','to':'d','type':'sub','value':'400','op':'dr'},
  {'from':'c','to':'d','type':'sub','value':'500','op':'cr'}
];

function resample(data) {
  var newData = [];
  var indexer = {};

  data.map(function(item, index) {
    //prepare indexer key
    var key = item.from + '_' + item.to;
    if (typeof indexer[key] === 'undefined') {
      indexer[key] = {from: item.from, to: item.to};
    }
    //adds or sub
    if (typeof indexer[key][item.type] === 'undefined') {
      indexer[key][item.type] = []
    }
    indexer[key][item.type].push({value: item.value, op: item.op})
    return [];
  })
  for( var key in indexer ){
    newData.push(indexer[key])
  }
  return newData;
}

var resampledData = resample(sampleData);

console.log(resampledData);

小心map,因为所有浏览器都不支持此功能。简单的for循环可以取代map

答案 1 :(得分:1)

这使用了一些ES6箭头函数和对象文字缩写,但你说你正在使用NodeJS所以它应该没问题

let a = [{"from":"a","to":"b","type":"add","value":"100","op":"cr"},{"from":"a","to":"b","type":"add","value":"200","op":"dr"},{"from":"a","to":"b","type":"add","value":"300","op":"cr"},{"from":"c","to":"d","type":"sub","value":"400","op":"dr"},{"from":"c","to":"d","type":"sub","value":"500","op":"cr"}];

let tmp = a.reduce((map, row) => {
  // create a key hash of "from" and "to"
  let key = [row.from, row.to].join(',');
  
  // the value to append to the "type" array
  let valueObj = { [row.value]: row.op };
  
  // ensure map[key][row.type] is an array
  map[key] = Object.assign({ [row.type]: [] }, map[key]);
  
  // add the value
  map[key][row.type].push(valueObj);
  return map;
}, Object.create(null));

let out = Object.keys(tmp).map(key => {
  // re-create the "from" and "to" properties from the key "hash"
  let k = key.split(',');
  
  return Object.assign({
    from: k[0],
    to: k[1]
  }, tmp[key]);
});

console.log(out);

答案 2 :(得分:-1)

这样做。这可以改进。

function parseInput(input) {
    var result = [];
    input.forEach(
        function(data) {
            var subData = {};
            subData[data.value] = data.op;
            var index = getMatchingIndex(result, data);
            if (index == -1) {
                var typeData = {};
                typeData[data.type] = [subData];

                var resData = {};
                resData.from = data.from;
                resData.to = data.to;
                resData[data.type] = [];
                resData[data.type].push(subData);
                result.push(resData);
            } else {
                result[index][data.type].push(subData);
            }
        }
    );
    return result;
}

function getMatchingIndex(result, data) {
    for (var i = 0; i < result.length; i++) {
        if (result[i].from === data.from &&
            result[i].to === data.to &&
            result[i].hasOwnProperty(data.type))
            return i;
    }
    return -1;
}

var input = [{
    'from': 'a',
    'to': 'b',
    'type': 'add',
    'value': '100',
    'op': 'cr'
}, {
    'from': 'a',
    'to': 'b',
    'type': 'add',
    'value': '200',
    'op': 'dr'
}, {
    'from': 'a',
    'to': 'b',
    'type': 'add',
    'value': '300',
    'op': 'cr'
}, {
    'from': 'c',
    'to': 'd',
    'type': 'sub',
    'value': '400',
    'op': 'dr'
}, {
    'from': 'c',
    'to': 'd',
    'type': 'sub',
    'value': '500',
    'op': 'cr'
}];

JSON.stringify(parseInput(input));