0

I want to covert combination of object from an object. For example:

Example:

    var obj1 = {city: "Canada", pincode: [300005, 300006, 300007], locations: ["Toronto", "Winnipeg", "Montreal"]};

Expected Output is:

    result = [{city: "Canada", pincode: 300005, location: "Toronto"}, {city: "Canada", pincode: 300005, location: "Winnipeg"}, {city: "Canada", pincode: 300005, location: "Montreal"}, {city: "Canada", pincode: 300006, location: "Toronto"}, {city: "Canada", pincode: 300006, location: "Winnipeg"}, {city: "Canada", pincode: 300006, location: "Montreal"},{city: "Canada", pincode: 300007, location: "Toronto"}, {city: "Canada", pincode: 300007, location: "Winnipeg"}, {city: "Canada", pincode: 300007, location: "Montreal"}]
Sirko
  • 72,589
  • 19
  • 149
  • 183

3 Answers3

0

Try this -> Map through pincodes and locartions and return the required object for each pincode and location.

var obj1 = { city: "Canada", pincode: [300005, 300006, 300007], locations: ["Toronto", "Winnipeg", "Montreal"] };

//map through the pincodes and locations
const resultArray = obj1.pincode.map((pincode) => {
  return obj1.locations.map((location, index) => {
    return { city: obj1.city, pincode: pincode, location: obj1.locations[index] }
  })
});
//flatten the result array 
[].concat.apply([], resultArray);
Nitha
  • 672
  • 5
  • 10
  • How many times are we going to write map because then again we have to iterate through locations and it won't be generic. And may be there would be another array then again do the code changes which is not seems to be a feasible solution. –  Oct 06 '22 at 06:51
  • Similar question -> https://stackoverflow.com/questions/8936610/how-can-i-create-every-combination-possible-for-the-contents-of-two-arrays @MukundKarn – Nitha Oct 06 '22 at 07:58
0
const result = [];
 var obj1 = {city: "Canada", pincode: [300005, 300006, 300007], locations: ["Toronto", "Winnipeg", "Montreal"]};
 obj1.pincode.map((val, idx) => {
     result.push({
         city: obj1.city,
         pincode: val,
         locations: obj1.locations[idx]
     })
 });
Shoaib
  • 7
  • 4
0

Here is a generic solution, which assumes that all the array typed properties will be broken down into array-elements, making a Cartesian product when more than one array is found in the given object.

It reuses code for cartesian product of arrays, and defines a few more helper functions:

  • toArray to wrap the argument into an array if it isn't one yet, or else just return the argument as-is. This is used to have an array version of all property values in the given object, and these arrays are passed on to get a cartesion product

  • zip to merge two equally-sized arrays into one array of pairs. This is used by combine:

  • combine to merge an array of keys and an array of values into one object. The values are those that come back from the cartesian product.

const cartesian = 
    data => data.reduce((a, b) => a.flatMap(x => b.map(y => [...x, y])), [[]]);
const toArray = a => [].concat(a);
const zip = (a, b) => a.map((v, i) => [v, b[i]]);
const combine = (keys, values) => Object.fromEntries(zip(keys, values));
// The main algorithm:
const expand = obj =>
    cartesian(Object.values(obj).map(toArray)).map(combine.bind(null, Object.keys(obj)));


// Example
const obj1 = {
    city: "Canada", 
    pincode: [300005, 300006, 300007], 
    locations: ["Toronto", "Winnipeg", "Montreal"]
}
const result = expand(obj1);
console.log(result);

So the steps performed are:

  • Take the values from the given object
  • Make them arrays is they are not yet, so "Canada" becomes ["Canada"]
  • Perform the Cartesian product on those arrays
  • Merge each combination from that product with the keys of the original object to turn that combination into an object
trincot
  • 317,000
  • 35
  • 244
  • 286