skip to Main Content

I have the following array:

[
    {
        "level": "level3",
        "category": "car"
    },
    {
        "level": "level1",
        "category": "bike"
    },
    {
        "level": "level2",
        "category": "car"
    },
    {
        "level": "level5",
        "category": "bike"
    }
]

I need to convert this to the following object:

newObj = {
     car: ['level3', 'level2'],
     bike: ['level5', 'level1'],
  };

What would be the best way to achieve this? Thanks in advance

3

Answers


  1. You could achieve what you want with many approaches:

    for...of approach

    const data = [ { "level": "level3", "category": "car" }, { "level": "level1", "category": "bike" }, { "level": "level2", "category": "car" }, { "level": "level5", "category": "bike" } ];
    const newObj = {};
    for (const item of data) {
      const {level,category} = item;
      if (newObj[category]) {
        newObj[category].push(level);
      } else {
        newObj[category] = [level];
      }
    }
    console.log(newObj);

    reduce approach

    const data = [ { "level": "level3", "category": "car" }, { "level": "level1", "category": "bike" }, { "level": "level2", "category": "car" }, { "level": "level5", "category": "bike" } ];
    const newObj = data.reduce((acc, item) => {
        const { level, category } = item;
        acc[category] = acc[category] || [];
        acc[category].push(level);
        return acc;
    }, {});
    console.log(newObj);

    The first approach is simple and understandable and the second is a more functional approach. But both approaches have a linear time complexity of O(n), choosing one of them is just a matter of personal preference and coding style.

    Login or Signup to reply.
  2. By using the function Array.prototype.reduce

    const array = [{        "level": "level3",        "category": "car"    },    { "level": "level1",        "category": "bike"    },    {        "level": "level2",        "category": "car"    },    {      "level": "level5",        "category": "bike"    }],
          result = array.reduce((a, {level, category}) => {
            (a[category] = a[category] || []).push(level);
            return a;
          }, {});
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  3. An old-school imperative approach with a linear runtime (that is double the size of your array, and you double the time it takes for the algorithm to finish)

    const origs = [
        {
            "level": "level3",
            "category": "car"
        },
        {
            "level": "level1",
            "category": "bike"
        },
        {
            "level": "level2",
            "category": "car"
        },
        {
            "level": "level5",
            "category": "bike"
        }
    ]
    
    const newObj = {}
        
    for (orig of origs) {
      if (orig.category && orig.level) {
        newObj[orig.category] = newObj[orig.category] ? newObj[orig.category].concat(orig.level) : [orig.level]
      }  
    }
    

    Also, it’s a good idea to watch for the presence of the fields category
    and level.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search