简体   繁体   中英

Converting object format in Javascript

I have an input array of objects, which each object has the following format:

{
 titleID: string,
 titleName: string,
 1af23_red: number,
 45ua6_blue: number
}

What I know is that:

  1. In every object, there will be always the keys titleID and titleName and then I will have several keys that have the format number_string .

  2. The titleID and titleName values will be different among the different objects

  3. The rest of the keys (1af23_red, 45ua6_blue, etc) will be the same in all objects and they will all have the same format 'id_name' So, if the first object has 1af23_red and 45ua6_blue as keys, all the rest will also have just those keys.

The type of array that I want back has the following format:

{
  color: {
    id
    name
  },
  data: Array<
  {
    title: {
      id
      name
    },
    rating
  }
  >
}

So, example of input:

[ 
  { 
    titleId: 'a',
    titleName: 'atitle',
    '1af_red': 50
    'ba2_blue': 40
  },
  {
    titleId: 'b',
    titleName: 'btitle',
    '1af_red': 30
    'ba2_blue': null
  },
  {
    titleId: 'c',
    titleName: 'ctitle',
    '1af_red': null
    'ba2_blue': 10
  }
]

I would expect back:

[
  {
    color: {
      id: '1af',
      name: 'red'
    },
    data: [
      {
        title: {
          id: 'a',
          name: 'atitle',
        },
        rating: 50
      }, 
      {
        title: {
          id: 'b',
          name: 'btitle',
        },
        rating: 30
      },
      {
        title: {
          id: 'c',
          name: 'ctitle',
        },
        rating: null
      }
    ]
  },
  {
    color: {
      id: 'ba2',
      name: 'blue'
    },
    data: [
      {
        title: {
          id: 'a',
          name: 'atitle',
        },
        rating: 40
      }, 
      {
        title: {
          id: 'b',
          name: 'btitle',
        },
        rating: null
      },
      {
        title: {
          id: 'c',
          name: 'ctitle',
        },
        rating: 10
      }
    ]
  }
]

I have tried doing this conversion with map and reduce but I am stuck. Is there an easy way to accomplish this?

Here you go.

Brief logic : Getting all the keys from the object at 0th index from data array. Looping over the keys, if key contains '_', pick the key, break it to form id and name pair, then map over all the data objects, get the score for that key and append it to the object with id and name values. Finally append this object to result array. Doing this for all the keys which contains '_'.

 const data = [ { titleId: 'a', titleName: 'atitle', '1af_red': 50, 'ba2_blue': 40 }, { titleId: 'b', titleName: 'btitle', '1af_red': 30, 'ba2_blue': null }, { titleId: 'c', titleName: 'ctitle', '1af_red': null, 'ba2_blue': 10 } ]; const keys = Object.keys(data[0]); const result = [] keys.map(key=> { if(key.indexOf('_')!==-1){ const item = {} const keyData = key.split('_') item.color = { id : keyData[0], name : keyData[1] } item.data = [] data.map(obj => { const newObj = {} newObj.title = { id : obj.titleId, name : obj.titleName } newObj.rating = obj[key]; item.data.push(newObj); }); result.push(item); } }); console.log(result); 

You could try that

 let elements = [ { titleId: 'a', titleName: 'atitle', '1af_red': 50, 'ba2_blue': 40 }, { titleId: 'b', titleName: 'btitle', '1af_red': 30, 'ba2_blue': null }, { titleId: 'c', titleName: 'ctitle', '1af_red': null, 'ba2_blue': 10 } ] let colors = [] let result = [] elements.forEach(currElem => { for(let attr in currElem){ if(attr != "titleId" && attr != "titleName"){ let color = attr.split("_") if(!colors.some(currColor => {return currColor == color[1]})){ colors.push({ "id": color[0], "name": color[1] }) } } } }) colors.forEach(currColor => { result.push({ "color" : currColor, "data": [] }) elements.forEach(currElement => { for(let attr in currElement){ let color = [] if(attr != "titleId" && attr != "titleName"){ color = attr.split("_") if(color[1] == currColor.name){ for(let i=0; i<result.length;i++){ if(result[i].color.name == color[1]){ result[i].data.push({ "title" : { "id": currElement.titleId, "name": currElement.titleName }, "rating":currElement[attr] }) break } } } } } }) }) console.log(result) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM