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

时间:2019-04-30 04:39:04

标签: javascript arrays typescript object ecmascript-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与hypen结合使用)找到正确的方法,以上述格式转换为单个对象。

有人可以帮我吗?

5 个答案:

答案 0 :(得分:5)

您可以将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);

答案 1 :(得分:4)

您的代码几乎在那里。但是不能保证对象键的顺序。在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)

答案 2 :(得分:2)

假设您要排除所有值为object的属性,则可以采用使用Object.entries()遍历内部对象和某些destructuring功能的通用思想。 / p>

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

答案 3 :(得分: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] }) 

})

答案 4 :(得分: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));