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"}]
CodePudding user response:
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);
CodePudding user response:
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]
})
});
CodePudding user response:
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 productzip
to merge two equally-sized arrays into one array of pairs. This is used bycombine
: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