如何在Typescript中将对象数组转换为具有动态键的单个对象

6

这个问题可能与经常问到的类似,但是这个问题有一些不同的方法。

在我的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 对象怎么办?应该怎么处理?应该丢弃吗? - Jack Bashford
可以丢弃Yes Criteria对象并获取上述单个对象。 - UI_Dev
5个回答

6
您可以使用 reduceObject.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);


4

你的代码已经快完成了。但是对象键(key)的顺序不能保证。在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
1
@UI_Dev 希望这个链接 https://dev59.com/jW035IYBdhLWcg3wQtsg 能帮到你。 - brk
@UI_Dev 有人做了。 - Pierre Arlaud

2
假设您想要排除所有值为object的属性,也许您可以采用这个通用的想法,使用Object.entries()来遍历内部对象和一些解构特性。最初的回答。

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;}


1
哦,天啊...我刚被打败了。这是我的解决方案。
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] }) 

})

0

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));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接