如何将对象数组转换为在打字稿中具有动态键的单个对象
Posted
技术标签:
【中文标题】如何将对象数组转换为在打字稿中具有动态键的单个对象【英文标题】:How to convert array of objects to single object which has dynamic key in typescript 【发布时间】:2019-09-18 17:01:18 【问题描述】:这个问题可能与常见问题类似,但这个问题有一些不同的方法。
在我的 Angular 7 应用程序中,我有以下 5 个数组,需要根据 id 使用动态键将其转换为下面的单个对象。
"enabled-41": true,
"enabled-42": true,
"enabled-43": true,
"enabled-44": true,
"enabled-45": false,
"abc-41": "some description 1",
"abc-42": "some description 12",
"abc-43": "some description 123",
"abc-44": "some description 1234",
"abc-45": null,
"def-41": "some description 2",
"def-42": "some description 23",
"def-43": "some description 234",
"def-44": "some description 2345",
"def-45": null,
"type-41": "def",
"type-42": "abc",
"type-43": "def",
"type-44": "abc",
"type-45": null,
"weight-41": "25",
"weight-42": "25",
"weight-43": "25",
"weight-44": "25",
"weight-45": null
let arr = [
"id": 41,
"abc": "some description 1",
"def": "some description 2",
"type": "def",
"Criteria":
"id": 5,
"question": "follow-up",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 42,
"abc": "some description 12",
"def": "some description 23",
"type": "abc",
"Criteria":
"id": 1,
"question": "coverage",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 43,
"abc": "some description 123",
"def": "some description 234",
"type": "def",
"Criteria":
"id": 4,
"question": "Price",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 44,
"abc": "some description 1234",
"def": "some description 2345",
"type": "abc",
"Criteria":
"id": 3,
"question": "Exchange",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 45,
"Criteria":
"id": 2,
"definition": "definition conent",
"question": "Random",
"status": true
,
"type": null,
"abc": null,
"def": null,
"weight": 0,
"enabled": false
];
let result = arr.reduce(function(obj, item)
obj[item] = item.value;
return obj;
, )
console.log(result);
我尝试过使用 reduce 函数,但无法根据动态键(用连字符连接 id)获得正确的方法来转换为上述格式的单个对象。
有人可以帮我解决这个问题吗?
【问题讨论】:
Criteria
对象呢?应该发生什么?它应该被丢弃吗?
是Criteria对象可以被丢弃,想得到同上的单个对象
【参考方案1】:
您的代码几乎就在那里。但是不能保证对象键的顺序。在reduce回调函数内部添加累加器中的键和对应的值。
在创建对象键时使用模板文字和方符号
let arr = [
"id": 41,
"abc": "some description 1",
"def": "some description 2",
"type": "def",
"Criteria":
"id": 5,
"question": "follow-up",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 42,
"abc": "some description 12",
"def": "some description 23",
"type": "abc",
"Criteria":
"id": 1,
"question": "coverage",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 43,
"abc": "some description 123",
"def": "some description 234",
"type": "def",
"Criteria":
"id": 4,
"question": "Price",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 44,
"abc": "some description 1234",
"def": "some description 2345",
"type": "abc",
"Criteria":
"id": 3,
"question": "Exchange",
"definition": "definition content",
"status": true
,
"weight": 25,
"enabled": true
,
"id": 45,
"Criteria":
"id": 2,
"definition": "definition conent",
"question": "Random",
"status": true
,
"type": null,
"abc": null,
"def": null,
"weight": 0,
"enabled": false
];
let result = arr.reduce(function(obj, item)
obj[`enabled-$item.id`] = item.enabled;
obj[`abc-$item.id`] = item.abc;
obj[`def-$item.id`] = item.def;
obj[`type-$item.id`] = item.type;
obj[`weight-$item.id`] = item.weight;
return obj;
, );
console.log(result)
【讨论】:
谢谢,对象键顺序有可能吗? @UI_Dev 希望此链接***.com/questions/5525795/… 对您有所帮助 @UI_Dev 有人做过【参考方案2】:您可以将reduce
与Object.keys
一起使用,并将您希望排除的所有键放在一个数组中并检查:
let arr = ["id":41,"abc":"some description 1","def":"some description 2","type":"def","Criteria":"id":5,"question":"follow-up","definition":"definition content","status":true,"weight":25,"enabled":true,"id":42,"abc":"some description 12","def":"some description 23","type":"abc","Criteria":"id":1,"question":"coverage","definition":"definition content","status":true,"weight":25,"enabled":true,"id":43,"abc":"some description 123","def":"some description 234","type":"def","Criteria":"id":4,"question":"Price","definition":"definition content","status":true,"weight":25,"enabled":true,"id":44,"abc":"some description 1234","def":"some description 2345","type":"abc","Criteria":"id":3,"question":"Exchange","definition":"definition content","status":true,"weight":25,"enabled":true,"id":45,"Criteria":"id":2,"definition":"definition conent","question":"Random","status":true,"type":null,"abc":null,"def":null,"weight":0,"enabled":false];
let exclude = ["id", "Criteria"];
let result = arr.reduce((acc, curr) =>
let id = curr.id;
Object.entries(curr).forEach(([k, v]) =>
if (!exclude.includes(k)) acc[`$k-$id`] = v;
);
return acc;
, );
console.log(result);
【讨论】:
【参考方案3】:假设您要排除所有值为 object
的属性,也许您可以采用这个通用的想法,即使用 Object.entries()
遍历内部对象和一些 destructuring
特征。
let arr=["id":41,"abc":"some description 1","def":"some description 2","type":"def","Criteria":"id":5,"question":"follow-up","definition":"definition content","status":true,"weight":25,"enabled":true,"id":42,"abc":"some description 12","def":"some description 23","type":"abc","Criteria":"id":1,"question":"coverage","definition":"definition content","status":true,"weight":25,"enabled":true,"id":43,"abc":"some description 123","def":"some description 234","type":"def","Criteria":"id":4,"question":"Price","definition":"definition content","status":true,"weight":25,"enabled":true,"id":44,"abc":"some description 1234","def":"some description 2345","type":"abc","Criteria":"id":3,"question":"Exchange","definition":"definition content","status":true,"weight":25,"enabled":true,"id":45,"Criteria":"id":2,"definition":"definition conent","question":"Random","status":true,"type":null,"abc":null,"def":null,"weight":0,"enabled":false];
let result = arr.reduce((obj, id, ...rest) =>
Object.entries(rest).forEach(([k, v]) =>
if (Object(v) !== v) obj[`$k-$id`] = v;
);
return obj;
, );
console.log(result);
.as-console background-color:black !important; color:lime;
.as-console-wrapper max-height:100% !important; top:0;
【讨论】:
【参考方案4】:哦,伙计……我刚刚被打败了。这是我的解决方案。
let arr= [] // hold the final object array
let keys = [] // temp item to hold the value of each key
// iterate over each key
Object.keys(input).forEach((key) =>
let pair = key.split('-') // split the key into the real key and the index
// if the index isn't in the array, push it there (this keeps the same order)
if (keys.indexOf(pair[1])===-1)
keys.push(pair[1])
// use object.assign to add the keys to the existing object in the right place in the array.
arr[keys.indexOf(pair[1])] = Object.assign(, arr[keys.indexOf(pair[1])], [pair[0]]: input[key], id: pair[1] )
)
【讨论】:
【参考方案5】:function getFilteredData(arr)
const result = ;
arr.forEach(item =>
const id, Criteria, ...rest = item;
Object.entries(rest).map(([key, value]) =>
result[`$key-$id`] = value;
);
);
return result;
let arr = [
id: 41,
abc: 'some description 1',
def: 'some description 2',
type: 'def',
Criteria:
id: 5,
question: 'follow-up',
definition: 'definition content',
status: true
,
weight: 25,
enabled: true
,
id: 42,
abc: 'some description 12',
def: 'some description 23',
type: 'abc',
Criteria:
id: 1,
question: 'coverage',
definition: 'definition content',
status: true
,
weight: 25,
enabled: true
,
id: 43,
abc: 'some description 123',
def: 'some description 234',
type: 'def',
Criteria:
id: 4,
question: 'Price',
definition: 'definition content',
status: true
,
weight: 25,
enabled: true
,
id: 44,
abc: 'some description 1234',
def: 'some description 2345',
type: 'abc',
Criteria:
id: 3,
question: 'Exchange',
definition: 'definition content',
status: true
,
weight: 25,
enabled: true
,
id: 45,
Criteria:
id: 2,
definition: 'definition conent',
question: 'Random',
status: true
,
type: null,
abc: null,
def: null,
weight: 0,
enabled: false
];
console.log(getFilteredData(arr));
【讨论】:
以上是关于如何将对象数组转换为在打字稿中具有动态键的单个对象的主要内容,如果未能解决你的问题,请参考以下文章