展平嵌套的对象数组,将键重命名为迭代器
Flatten nested array of objects, renaming keys to an iterator
我有一个对象数组,每个对象如下所示(轮询响应):
{
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"responses": [
{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
},
我需要展平通过 responses
键访问的数组,以便每个对象键控到其迭代器。
最终对象应如下所示:
{
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"label1": "Ducey",
"name1": "Doug Ducey",
"party1": "Republican",
"incumbent1": true
"label2": "Farley",
"name2": "Steve Farley",
"party2": "Democrat",
"incumbent2": false
"label3": "Other",
"name3": "Other",
"party3": null,
"incumbent3": false
"label4": "Undecided",
"name4": "Undecided",
"party4": null,
"incumbent4": false
},
在展平或对集合执行时不重命名对象键。
我尝试了几种解决方案,但想在真正深入研究之前看看是否有简单的 es6 方法。
使用数组 .reduce
方法在这里可能效果很好。由于 reduce
回调将接收当前索引作为第三个参数,您可以使用它来创建您要查找的键。
示例:
const myArray = [
{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
const flattened = myArray.reduce((flat, item, index) => ({
...flat,
...Object.keys(item).reduce((numbered, key) => ({
...numbered,
[key + (index+1)]: item[key],
}), {}),
}), {});
console.log(flattened);
您可以使用 forEach
遍历 responses
数组并在您的对象上为每个对象中的 entries
分配一个新键。在那之后 delete
原来的 responses
数组:
let obj = {"slug": "18-AZ-Gov-GE-DvF","name": "2018 Arizona Gubernatorial GE","tags": [],"charts": [],"election_date": "2018-11-06","n_polls": 1,"created_at": "2017-06-13T13:32:26.000Z","responses": [ { "label": "Ducey", "name": "Doug Ducey", "party": "Republican", "incumbent": true }, { "label": "Farley", "name": "Steve Farley", "party": "Democrat", "incumbent": false }, { "label": "Other", "name": "Other", "party": null, "incumbent": false }, { "label": "Undecided", "name": "Undecided", "party": null, "incumbent": false }]}
obj.responses.forEach((item, i) => {
// item is one object from responses
// i is the index starting at 0. Concat that on the key
Object.entries(item).forEach(([k, v]) => obj[k+(i+1)] = v)
})
// no need for obj.responses any more
delete obj.responses
console.log(obj)
一种方法会使用一些较新的好东西,包括 spread
, destructuring assignment
, template literals
, entries
and most importantly reduce
。
主要要点是使用一个reducer将responses
数组转换为一个新对象,每个元素对象使用一个辅助reducer来修改带有迭代器计数的键,并将值分配给外部对象新密钥。
这种方法的一个主要好处是原始对象(包括其子对象)没有被修改(阅读:没有副作用)。
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
完整的工作示例:
const orig = {
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"responses": [{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
};
const {responses, ...foo} = orig;
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
console.log({flattened: {...foo, ...flattened}});
console.log({orig});
您可以解构您的响应和其他数据,然后使用索引键将每个响应减少到一个对象,然后 assemble 通过对象扩展运算符得到结果:
const { responses, ...other } = data
const indexedResponses = responses.reduce((acc, r, i) => {
Object.entries(r).forEach(([key, value]) => {
acc[`${key}${i + 1}`] = value
})
return acc
}, {})
const result = { ...other, ...indexedResponses }
我有一个对象数组,每个对象如下所示(轮询响应):
{
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"responses": [
{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
},
我需要展平通过 responses
键访问的数组,以便每个对象键控到其迭代器。
最终对象应如下所示:
{
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"label1": "Ducey",
"name1": "Doug Ducey",
"party1": "Republican",
"incumbent1": true
"label2": "Farley",
"name2": "Steve Farley",
"party2": "Democrat",
"incumbent2": false
"label3": "Other",
"name3": "Other",
"party3": null,
"incumbent3": false
"label4": "Undecided",
"name4": "Undecided",
"party4": null,
"incumbent4": false
},
我尝试了几种解决方案,但想在真正深入研究之前看看是否有简单的 es6 方法。
使用数组 .reduce
方法在这里可能效果很好。由于 reduce
回调将接收当前索引作为第三个参数,您可以使用它来创建您要查找的键。
示例:
const myArray = [
{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
const flattened = myArray.reduce((flat, item, index) => ({
...flat,
...Object.keys(item).reduce((numbered, key) => ({
...numbered,
[key + (index+1)]: item[key],
}), {}),
}), {});
console.log(flattened);
您可以使用 forEach
遍历 responses
数组并在您的对象上为每个对象中的 entries
分配一个新键。在那之后 delete
原来的 responses
数组:
let obj = {"slug": "18-AZ-Gov-GE-DvF","name": "2018 Arizona Gubernatorial GE","tags": [],"charts": [],"election_date": "2018-11-06","n_polls": 1,"created_at": "2017-06-13T13:32:26.000Z","responses": [ { "label": "Ducey", "name": "Doug Ducey", "party": "Republican", "incumbent": true }, { "label": "Farley", "name": "Steve Farley", "party": "Democrat", "incumbent": false }, { "label": "Other", "name": "Other", "party": null, "incumbent": false }, { "label": "Undecided", "name": "Undecided", "party": null, "incumbent": false }]}
obj.responses.forEach((item, i) => {
// item is one object from responses
// i is the index starting at 0. Concat that on the key
Object.entries(item).forEach(([k, v]) => obj[k+(i+1)] = v)
})
// no need for obj.responses any more
delete obj.responses
console.log(obj)
一种方法会使用一些较新的好东西,包括 spread
, destructuring assignment
, template literals
, entries
and most importantly reduce
。
主要要点是使用一个reducer将responses
数组转换为一个新对象,每个元素对象使用一个辅助reducer来修改带有迭代器计数的键,并将值分配给外部对象新密钥。
这种方法的一个主要好处是原始对象(包括其子对象)没有被修改(阅读:没有副作用)。
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
完整的工作示例:
const orig = {
"slug": "18-AZ-Gov-GE-DvF",
"name": "2018 Arizona Gubernatorial GE",
"tags": [],
"charts": [],
"election_date": "2018-11-06",
"n_polls": 1,
"created_at": "2017-06-13T13:32:26.000Z",
"responses": [{
"label": "Ducey",
"name": "Doug Ducey",
"party": "Republican",
"incumbent": true
},
{
"label": "Farley",
"name": "Steve Farley",
"party": "Democrat",
"incumbent": false
},
{
"label": "Other",
"name": "Other",
"party": null,
"incumbent": false
},
{
"label": "Undecided",
"name": "Undecided",
"party": null,
"incumbent": false
}
]
};
const {responses, ...foo} = orig;
const flattened = responses.reduce((o, g, i) => {
Object.entries(g).reduce((t, [k, v]) => {
t[`${k}${i + 1}`] = v;
return t;
}, o);
return o;
},
{});
console.log({flattened: {...foo, ...flattened}});
console.log({orig});
您可以解构您的响应和其他数据,然后使用索引键将每个响应减少到一个对象,然后 assemble 通过对象扩展运算符得到结果:
const { responses, ...other } = data
const indexedResponses = responses.reduce((acc, r, i) => {
Object.entries(r).forEach(([key, value]) => {
acc[`${key}${i + 1}`] = value
})
return acc
}, {})
const result = { ...other, ...indexedResponses }