skip to Main Content

I have 2 objects, as such:

costsObj = {
  Honda: 24000,
  BMW: 55000,
  Toyota: 22000
};

stockObj = {
  Honda: 5,
  BMW: 1,
  Toyota: 2
}

I want to combine the 2 objects into 1 array of objects that looks like:

carsArr = [
  {brand: "Honda", cost: 24000, stock: 5},
  {brand: "BMW", cost: 55000, stock: 1},
  {brand: "Toyota", cost: 22000, stock: 2}
]

I have achieved this by using map(), for(), and forEach():

  // Use costsObj to create new array
  carsArr = Object.keys(costsObj).map(brand => {
    return { brand, cost: costsObj[brand], stock: 0 };
  });

  // Add data from stockObj to new carsArr
  for (const [key, value] of Object.entries(stockObj)) {
    carsArr.forEach((item, index)=>{
      if(item.term == key) {
        carsArr[index].stock = value;
      }
    })
  };

But this feels clunky and that there could/should be a better way, especially if I want to combine data from more objects in the future, eg:

carsArr = [
  {brand: "Honda", model: "Accord", cost: 24000, stock: 5},
  {brand: "BMW", model: "3 series", cost: 55000, stock: 1},
  {brand: "Toyota", model: "Camry", cost: 22000, stock: 2}
]

Does anyone know if there is a better way to combine the data from many objects into one array of objects?

4

Answers


  1. You can do it in one line like this:

    const cost = {
      Honda: 24000,
      BMW: 55000,
      Toyota: 22000
    }
    
    const stock = {
      Honda: 5,
      BMW: 1,
      Toyota: 2
    }
    
    const model = {
      Honda: 'Accord',
      BMW: '3 series',
      Toyota: 'Camry'
    }
    
    const cars = Object.entries({model, cost, stock}).reduce((a, [b, c]) =>
      (Object.entries(c).forEach(([d, e]) => (a[d]??={brand: d})[b] = e), a), {})
    
    console.log(Object.values(cars))

    It looks at each of the input objects, and considers the name of the object to be the same as the key that will appear in the final result. Therefore, the object cost will have entries using the key cost: in the result.

    It uses reduce to iterate over values and place them in an object keyed by the brand. It then uses Object.values() to get just the values of that object, once it has been built.

    Login or Signup to reply.
  2. You can do this like this.

    const cost = {
      Honda: 24000,
      BMW: 55000,
      Toyota: 22000
    }
    
    const stock = {
      Honda: 5,
      BMW: 1,
      Toyota: 2
    }
    
    const cars = Object.keys(cost).reduce((acc, brand) => {
        return [...acc, {brand, cost: cost[brand], stock: stock[brand]}];
    }, []);
    
    console.log(cars);

    Also you can combine more objects easily.

    return [...acc, {brand, model: model[brand], cost: cost[brand], stock: stock[brand]}];
    
    Login or Signup to reply.
  3. Use Object.entries to get an array of key value pairs from costsObj, then use Array#map to convert each entry to the objects you want.

    const costsObj = {
      Honda: 24000,
      BMW: 55000,
      Toyota: 22000
    }
    
    const stockObj = {
      Honda: 5,
      BMW: 1,
      Toyota: 2
    }
    
    const carsArr = Object.entries(costsObj)
      .map(([k, v]) => ({ brand: k, cost: v, stock: stockObj[k] }));
    
    console.log(carsArr)
    Login or Signup to reply.
  4. I have found the following code, But it will merge objects and arrays in a specific way.

    let costsObj = {
      Honda: 24000,
      BMW: 55000,
      Toyota: 22000
    };
    
    let stockObj = {
      Honda: 5,
      BMW: 1,
      Toyota: 2
    }
    
    
    
    let allObjects = {
      cost: costsObj,
      stock: stockObj /*, MoreObjectsHere */
    }
    let combined = Object.keys(allObjects[Object.keys(allObjects)[0]]).map(key => {
      return Object.keys(allObjects).reduce((obj, objectKey) => {
        obj[objectKey] = allObjects[objectKey][key];
        obj['brand'] = key;
        return obj
      }, {});
    });
    
    console.log(combined);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search