[英]Extracting key value from object into array of objects with specific fields
So I have this data:所以我有这个数据:
fields = ['a', 'b', 'c']
data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5} ... ]
and I want to be able (preferred with lodash) to be able to get to this:我希望能够(首选 lodash)能够做到这一点:
newData = [{r:1, h:5, values: [{name: 'a', value: 2},{name: 'b', value: 3}, {name: 'c', value: 4}], .....]
Meaning only the fields from the 'fields' object be taken out of each object in array (they always exist) and put into 'values' property that has an array of them in the format displayed here.这意味着只有来自“字段”object 的字段从数组中的每个 object 中取出(它们始终存在)并放入具有此处显示格式的数组的“值”属性中。
Would love to hear suggestions of the cleanest way to achieve this!很想听听关于实现这一目标的最干净方法的建议!
I did this:我这样做了:
function something(data, fields) {
const formattedData = _.map(data, (currData) => {
const otherFields = _.omit(currData, fields)
return {
...otherFields,
values: _.flow(
currData => _.pick(currData, fields),
pickedFields => _.toPairs(pickedFields),
pairs => _.map(pairs, pair => {
return { name: pair[0], value: pair[1] }
})
)(currData)
}
})
return formattedData
}
which works, but I'm wondering if it isn't a bit complicated.哪个有效,但我想知道它是否有点复杂。
You could map
through the objects in data and then check if the key is in the fields array:您可以通过数据中的对象
map
,然后检查键是否在字段数组中:
fields = ["a", "b", "c"]; data = [ { r: 1, a: 2, b: 3, c: 4, h: 5 }, { r: 4, a: 9, b: 1, c: 4, h: 5 }, ]; let newData = data.map((o) => { let newObject = {}; newObject.values = []; for (let k in o) { if (fields.includes(k)) { newObject.values.push({ name: k, value: o[k] }); } else { newObject[k] = o[k]; } } return newObject; }); console.log(newData);
You could destructure the object, pick the wanted properties and return the rest of the object with wanted values.您可以解构 object,选择所需属性并返回 object 的 rest 和所需值。
const fields = ['a', 'b', 'c'], data = [{ r: 1, a: 2, b: 3, c: 4, h: 5 }, { r: 4, a: 9, b: 1, c: 4, h: 5 }], result = data.map(o => { const values = fields.map(name => { let value; ({ [name]: value, ...o } = o); return { name, value }; }); return {...o, values }; }); console.log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
The _.flow()
method creates a function, which you can extract and name. _.flow()
方法创建一个 function,您可以对其进行提取和命名。 In addition, the 1st function in the flow, accepts more than 1 parameter, so you don't need to pass it explicitly.另外,流程中的第一个 function 接受多个参数,因此您不需要显式传递它。 Since
_.toPairs()
is unary, you don't need to wrap it in an arrow function.由于
_.toPairs()
是一元的,因此您不需要将其包装在箭头 function 中。 The object creation is a bit annoying. object 的创建有点烦人。 I've used
_.zipObject()
, but it's still cumbersome.我用过
_.zipObject()
,但它仍然很麻烦。
Now you can use the function create by _.flow()
in your main function, and it's pretty readable:现在您可以在您的主 function 中使用由
_.flow()
创建的 function,它非常易读:
const { flow, pick, toPairs, map, partial, zipObject, omit } = _ const propsToObjs = flow( pick, toPairs, pairs => map(pairs, partial(zipObject, ['name', 'value'])), ) const fn = (data, fields) => map(data, currData => ({...omit(currData, fields), values: propsToObjs(currData, fields) })) const fields = ['a', 'b', 'c'] const data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5}] const result = fn(data, fields) console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Using lodash/fp, we can make the flow function even nicer, since lodash/fp functions are auto-curried and iteratee-first data-last (not the reversed order of parameters):使用 lodash/fp,我们可以使流程 function 更好,因为 lodash/fp 函数是自动柯里化的并且迭代优先数据最后(不是参数的相反顺序):
const { flow, pick, toPairs, map, partial, zipObject, omit } = _ const propsToObjs = flow( pick, toPairs, map(zipObject(['name', 'value'])) ) const fn = fields => map(currData => ({...omit(fields, currData), values: propsToObjs(fields, currData) })) const fields = ['a', 'b', 'c'] const data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5}] const result = fn(fields)(data) console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.