使用TypeScript / JS / RxJS / map / reduce / filter将嵌套JSON转换为平面JSON,

时间:2016-07-28 13:55:00

标签: javascript json underscore.js lodash data-conversion

我如何转换(没有复杂的foreach循环),如果可能的话,使用现有的JS-Libraries(RxJS for Observables,Lodash / Underscore / what)

以下结构:

{
    "result": [
        {
            "content": {
                "resources": [
                    {
                        "prop": [
                            {
                                "key": "BAR",
                                "value": "Bar getting better"
                            },
                            {
                                "key": "FOO",
                                "value": "Foo is cool"
                            }
                        ]
                    }
                ]
            }
        }
    ]
}
很容易进入这个?

{
    "BAR": "Bar getting better",
    "FOO": "Foo is cool"
}

4 个答案:

答案 0 :(得分:1)

对于此特定数据结构,您可以使用reduce()并返回对象。

select t1.transactionid, t1.id1, t1.id2, min(t2.transactionid) as partnerid
from Transaction t1, Partner t2 where t1.id1 = t2.id1(+) and t1.id2 = t2.id2(+)
group by t1.transactionid, t1.id1, t1.id2
order by t1.transactionid, t1.id1, t1.id2

带有箭头功能的

ES6 版本

var data = {"result":[{"content":{"resources":[{"prop":[{"key":"BAR","value":"Bar getting better"},{"key":"FOO","value":"Foo is cool"}]}]}}]}

var result = data.result[0].content.resources[0].prop.reduce(function(r, e) {
  r[e.key] = e.value;
  return r;
}, {});

console.log(result);

答案 1 :(得分:1)

在Lodash中,使用_.keyBy然后_.mapValues

var data = {"result":[{"content":{"resources":[{"prop":[{"key":"BAR","value":"Bar getting better"},{"key":"FOO","value":"Foo is cool"}]}]}}]},
    input = data.result[0].content.resources[0].prop;

var result = _.mapValues(_.keyBy(input, 'key'), 'value');

console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

答案 2 :(得分:0)

这是一个使用vanilla Javascript ES6 的解决方案,但它有点复杂(我没有测试过):

var data = ...
var resultData = {}

data.result.forEach(result => result.content.resources.forEach(resource => resource.prop.forEach(prop => resultData[prop.key] = prop.value)))

或者如果你只有一个用于顶层数组的项目,那么试试这个 Javascript ES5

var data = ...
var resultData = {}

data.result[0].content.resources[0].prop.forEach(function(prop) {
    resultData[prop.key] = prop.value
});

答案 3 :(得分:0)

此处其他解决方案的问题是

  1. 他们在data.result[0].content.resources[0].prop选择了数组,但没有考虑到resultresources数组的长度大于。< / LI>
  2. 嵌套forEach很难理解和推理。
  3. 为了解决这个问题,我创建了一个小型库deep-reduce,它可以帮助您减少/解开深层嵌套对象中的值。 deep-reduceArray.prototype.reduce类似,但它在嵌套对象/数组中深入遍历。

    在您的数据上,您可以像这样使用它

    // if path is ending in prop.number, 
    // then `item` is the object we want to untangle
    let untanglePropItems = (reduced, item, path) => {
      if (path.match(/prop\.\d+$/)) {
        reduced[item.key] = item.value
      }
      return reduced
    }
    
    // the reduced value is returned
    let reduced = deepReduce(deepNestedObject, untanglePropItems)
    

    Here is a demo in RunKit