[英]Convert JSON to Array of Objects using lodash
I have a JSON object in NoSql database in this format.我在这种格式的 NoSql 数据库中有一个 JSON 对象。 We are getting this data after migrating some records from some other database and these are multi-valued fields.(Basically we are trying to clean the data for further processing).
我们在从其他数据库迁移一些记录后获取这些数据,这些是多值字段。(基本上我们正在尝试清理数据以进行进一步处理)。
{
"BPContName":"aName;bName;cName",
"BPContEmail":"aEmail;bEmail;cEmail",
"BPContPWID":"aPWID;bPWID;cPWID"
}
I want to add another key "bpTableDataName" in the same JSON which should have this format and values,我想在同一个 JSON 中添加另一个键“bpTableDataName”,它应该具有这种格式和值,
"bpTableDataName": [
{
"name": "aName",
"email": "aEmail",
"pwdid": "aPWID"
},
{
"name": "bName",
"email": "bEmail",
"pwdid": "bPWID"
},
{
"name": "cName",
"email": "cEmail",
"pwdid": "cPWID"
}
],
Is there a way we can achieve this using lodash?有没有办法使用 lodash 来实现这一点?
Try following code -尝试以下代码 -
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>
You can use split()
to split the values into an array.您可以使用
split()
将值拆分为数组。 Then iterate over the array and create the require json and then push that into results.然后遍历数组并创建 require json,然后将其推送到结果中。
Check this out.看一下这个。
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)
You could reduce
the entries returned by Object.entries
like this:您可以像这样
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
returns an array of key-value pair. Object.entries
返回一个键值对数组。 Loop through each of themsplit
the each value at ;
split
每个值;
BPCont
part and making it lowerCase
BPCont
部分并使其lowerCase
splits
and update specific keys of objects at each indexsplits
并更新每个索引处对象的特定键Update:更新:
Since you have an extra d
in the output's key, you can create a mapping object:由于您在输出的键中有一个额外的
d
,您可以创建一个映射对象:
propertyMap = {
"BPContName": "name",
"BPContEmail": "email",
"BPContPWID": "pwdid"
}
And inside the reduce
, change the replace
code to this:在
reduce
,将replace
代码更改为:
key = propertyMap[key]
Using Object.assign
, Object.entries
, Array#map
and the spread operator make this trivial使用
Object.assign
、 Object.entries
、 Array#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);
Of course, it wouldn't be me without a one-liner当然,没有单线就不会是我
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);
You can use lodash's _.flow()
to create a function.你可以使用 lodash 的
_.flow()
来创建一个函数。 Use _.map()
with _.overArgs()
to create a function that splits the values, format the key, and then converts them to an array of pairs using _.unzip()
, for example [['name', 'x'], ['name', 'y']]
.使用
_.map()
和_.overArgs()
创建一个函数来拆分值,格式化键,然后使用_.unzip()
将它们转换为对的数组,例如[['name', 'x'], ['name', 'y']]
。 Transpose the array of arrays with _.unzip()
to combine pairs of different properties.使用
_.unzip()
转置数组数组以组合不同的属性对。 Then use _.map()
to iterate, and convert each array of pairs to an object using _.fromPairs()
.然后使用
_.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>
Basically what you need is to zip
it.基本上你需要的是
zip
它。
Snippet:片段:
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>
Note, the sequence of the parameters we have to put such a way, the original object give us values when using Object.values
or giving us keys when using Object.keys
usually it is alphabetical order.注意,我们必须这样放置参数的顺序,原始对象在使用
Object.values
时给我们值或在使用Object.keys
时给我们键通常是按字母顺序排列的。 But, In case in any env the order is not guranted we can sort it with a sequence of keys as a metadata.但是,如果在任何环境中都不能保证顺序,我们可以使用一系列键作为元数据对其进行排序。
Or else you can explicitly pass the arguments like:否则,您可以显式传递参数,例如:
(obj.BPContName.split(';'), obj.BPContEmail.split(';'), obj.BPContPWID.split(';'))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.