使用lodash将JSON转换为对象数组

时间:2019-03-19 11:52:28

标签: javascript arrays node.js json lodash

我在NoSql数据库中有这种格式的JSON对象。我们是从其他数据库迁移了一些记录后得到的数据,这些是多值字段。(基本上,我们正在尝试清理数据以进行进一步处理)。

{
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}

我想在同一JSON中添加另一个键“ bpTableDataName”,该键应具有此格式和值,

"bpTableDataName": [
    {
      "name": "aName",
      "email": "aEmail",
      "pwdid": "aPWID"
    },
    {
      "name": "bName",
      "email": "bEmail",
      "pwdid": "bPWID"
    },
    {
      "name": "cName",
      "email": "cEmail",
      "pwdid": "cPWID"
    }
  ],

有没有一种方法可以使用lodash来实现?

6 个答案:

答案 0 :(得分:1)

尝试以下代码-

o = {
  "BPContName": "aName;bName;cName",
  "BPContEmail": "aEmail;bEmail;cEmail",
  "BPContPWID": "aPWID;bPWID;cPWID"
}

map = { "BPContName" : "name", "BPContEmail": "email", "BPContPWID": "pwdid" }

const result = _.reduce(o, (arr, v, k) => ( v.split(";").forEach((x,i) => _.set(arr, `${i}.${map[k]}`, x)), arr ), [])
   
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

答案 1 :(得分:0)

您可以使用split()将值拆分为一个数组。 然后遍历数组并创建require json,然后将其推送到结果中。

检查一下。

var data = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}
var names = data.BPContName.split(';');
var emails = data.BPContEmail.split(';');
var pwids = data.BPContPWID.split(';');

var results = [];

for(var i = 0 ; i < names.length; i++) {
  var obj = {
    name: names[i],
    email: emails[i],
    pwdid: pwids[i]
  }
  results.push(obj);
}

console.log(results)

答案 2 :(得分:0)

您可以reduce这样Object.entries返回的条目:

let obj = {
  "BPContName": "aName;bName;cName",
  "BPContEmail": "aEmail;bEmail;cEmail",
  "BPContPWID": "aPWID;bPWID;cPWID"
}

let bpTableDataName = Object.entries(obj).reduce((r, [key, value]) => {
  let splits = value.split(";");
  key = key.replace("BPCont", "").toLowerCase();
  splits.forEach((split, i) => (r[i] = r[i] || {})[key] = split)
  return r;
}, [])

obj.bpTableDataName = bpTableDataName;

console.log(obj)

  • Object.entries返回一个键值对数组。遍历每个人
  • split;的每个值
  • 通过删除BPCont部分并将其制成lowerCase
  • 来获取密钥
  • 遍历splits,并在每个索引处更新对象的特定键

更新:

由于输出键中有额外的d,因此可以创建映射对象:

propertyMap = {
  "BPContName": "name",
  "BPContEmail": "email",
  "BPContPWID": "pwdid"
}

reduce内,将replace代码更改为此:

key = propertyMap[key]

答案 3 :(得分:0)

使用Object.assignObject.entriesArray#map和散布运算符使这个琐碎事

    const inputdata = {
        "BPContName":"aName;bName;cName",
        "BPContEmail":"aEmail;bEmail;cEmail",
        "BPContPWID":"aPWID;bPWID;cPWID"
    };

    const t1=Object.assign({},...Object.entries(inputdata).map(([k,v])=>({[k]:v.split(';')})));
    inputdata.bpTableDataName=t1.BPContName.map((name,i)=>({name,email:t1.BPContEmail[i],pwdid:t1.BPContPWID[i]}));
    console.log(inputdata);

当然,没有一线人就不会是我

const obj = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
};
// one line to rule them all
obj.bpTableDataName=Object.entries(obj).reduce((r,[k,v])=>(v.split(';').forEach((v,i)=>(r[i]=r[i]||{})[{BPContName:'name',BPContEmail:'email',BPContPWID:'pwdid'}[k]]=v),r),[]);
//
console.log(obj);

答案 4 :(得分:0)

您可以使用lodash的_.flow()创建一个函数。将_.map()_.overArgs()一起使用以创建一个函数,该函数可以拆分值,格式化键,然后使用_.unzip()将它们转换为成对的数组,例如[['name', 'x'], ['name', 'y']]。用_.unzip()转置数组以组合成对的不同属性。然后使用_.map()进行迭代,并使用_.fromPairs()将每个成对的数组转换为一个对象。

const { flow, partialRight: pr, map, unzip, overArgs, times, size, constant, split, fromPairs } = _

const keysMap = new Map([['BPContName', 'name'], ['BPContEmail', 'email'], ['BPContPWID', 'pwdid']])

const formatKey = key => keysMap.get(key)
const splitVals = pr(split, ';')

const fn = flow(
  pr(map, overArgs(
    (vals, k) => unzip([vals, times(size(vals), constant(k))]),
    [splitVals, formatKey])
  ),
  unzip, // transpose
  pr(map, fromPairs) // convert each pairs array to object
)

const data = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}

const results = fn(data)

console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

答案 5 :(得分:0)

基本上,您需要zip

摘要:

let obj = {"BPContName":"aName;bName;cName","BPContEmail":"aEmail;bEmail;cEmail","BPContPWID":"aPWID;bPWID;cPWID"},
    res = _.zipWith(
      ..._.map(obj, v => v.split(';')),
      (name, email, pwid) => ({name, email, pwid})
    );
    
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

请注意,我们必须采用这种方式设置参数的顺序,原始对象在使用Object.values时给我们值,在使用Object.keys时给我们键,通常是字母顺序。但是,如果在任何环境中都无法保证顺序,我们可以使用一系列键作为元数据对其进行排序。

否则,您可以显式传递以下参数:

(obj.BPContName.split(';'), obj.BPContEmail.split(';'), obj.BPContPWID.split(';'))