I found here this code and works good. But I also need to know the "id" which is multible in use. e.g. in another array
var data = [
{"id":"1","Group":"Wohnzimmer","Light":"Diele", "type":"ct"},
{"id":"1","Group":"Wohnzimmer","Light":"Diele", "type":"ct"},
{"id":"2","Group":"Wohnzimmer","Light":"Diele", "type":"bri"},
{"id":"3","Group":"Wohnzimmer","Light":"Diele", "type":"color"},
{"id":"3","Group":"Wohnzimmer","Light":"Diele", "type":"color"},
]
var a = data.reduce((accumulator, current) => {
if (checkIfAlreadyExist(current)) {
return accumulator;
} else {
return [...accumulator, current];
}
function checkIfAlreadyExist(currentVal) {
return accumulator.some((item) => {
return (item.id === currentVal.id &&
item.Light === currentVal.Light &&
item.type === currentVal.type);
});
}
}, []);
console.log(a);
Reduced (it works fine!):
[{
Group: "Wohnzimmer",
id: "1",
Light: "Diele",
type: "ct"
}, {
Group: "Wohnzimmer",
id: "2",
Light: "Diele",
type: "bri"
}, {
Group: "Wohnzimmer",
id: "3",
Light: "Diele",
type: "color"
}]
Now, I need also the result of the deleted objects, like the following:
[{
Group: "Wohnzimmer",
id: "1",
Light: "Diele",
type: "ct"
},{
Group: "Wohnzimmer",
id: "3",
Light: "Diele",
type: "color"
}]
You can do this efficiently in linear time:
let key = obj => [obj.id, obj.Light, obj.type].join('##')
let seen = new Set,
unique = [],
removed = []
for (let obj of data) {
let k = key(obj);
(seen.has(k) ? removed : unique).push(obj)
seen.add(k)
}
use array.prototype.map and array.prototype.some
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){
return valueArr.indexOf(item) != idx
});
console.log(isDuplicate);
Using you current logic you could archive your preferred output with small changes, use a object instead with two arrays instead.
var data = [
{ id: "1", Group: "Wohnzimmer", Light: "Diele", type: "ct" },
{ id: "1", Group: "Wohnzimmer", Light: "Diele", type: "ct" },
{ id: "2", Group: "Wohnzimmer", Light: "Diele", type: "bri" },
{ id: "3", Group: "Wohnzimmer", Light: "Diele", type: "color" },
{ id: "3", Group: "Wohnzimmer", Light: "Diele", type: "color" },
];
var { unique, removed } = data.reduce(
(accumulator, current) => {
if (checkIfAlreadyExist(current)) {
return {
...accumulator,
removed: [...accumulator.removed, current],
};
} else {
return {
...accumulator,
unique: [...accumulator.unique, current],
};
}
function checkIfAlreadyExist(currentVal) {
return accumulator.unique.some((item) => {
return (
item.id === currentVal.id &&
item.Light === currentVal.Light &&
item.type === currentVal.type
);
});
}
},
{
unique: [],
removed: [],
}
);
console.log("Unique");
console.log(unique);
console.log("Removed");
console.log(removed);
Just create another array to store deleted items and if checkIfAlreadyExist returns true push current into the array.
var data = [
{"id":"1","Group":"Wohnzimmer","Light":"Diele", "type":"ct"},
{"id":"1","Group":"Wohnzimmer","Light":"Diele", "type":"ct"},
{"id":"2","Group":"Wohnzimmer","Light":"Diele", "type":"bri"},
{"id":"3","Group":"Wohnzimmer","Light":"Diele", "type":"color"},
{"id":"3","Group":"Wohnzimmer","Light":"Diele", "type":"color"},
]
var deleted = []
var a = data.reduce((accumulator, current) => {
if (checkIfAlreadyExist(current)) {
deleted.push(current)
return accumulator;
} else {
return [...accumulator, current];
}
function checkIfAlreadyExist(currentVal) {
return accumulator.some((item) => {
return (item.id === currentVal.id &&
item.Light === currentVal.Light &&
item.type === currentVal.type);
});
}
}, []);
console.log(a);
console.log(deleted)
Related
I am trying to achieve an operation where Ι am not sure where to start with.
Down below is my initial object:
[
{ type: "1", name: "Anthony" },
{
type: "1",
name: "Linus",
},
{
type: "2",
name: "Sebastin",
},
]
What I am trying to achieve is to move the objects which has same type inside an array and have a key value, named title and string type.
I am trying to produce an output equivalent to this and I am not sure where to begin with. Any help will be useful and appreciated. Thanks in advance <3
[
{
title: "1",
sub_items: [
{
type: "1",
name: "Anthony",
},
{
type: "1",
name: "Linus",
},
],
},
{
type: "2",
name: "Sebastin",
},
];
You can use Array.reduce() to group the input items by type/title and create the desired output:
const input = [{ "type":"1", "name":"Anthony" }, { "type": "1", "name": "Linus" }, { "type":"2", "name":"Sebastin" }]
const result = Object.values(input.reduce((acc, { type, name }) => {
acc[type] = acc[type] || { title: type, sub_items: [] };
acc[type].sub_items.push({ type, name });
return acc;
}, {}));
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
You can make it with Array.reduce
const data = [
{ type: "1", name: "Anthony" },
{
type: "1",
name: "Linus",
},
{
type: "2",
name: "Sebastin",
},
];
const output = data.reduce((acc, curr, index, list) => {
const matchNodes = list.filter((node) => node.type === curr.type);
if (matchNodes.length > 1) {
const accNode = acc.find((item) => item.title === curr.type);
if (accNode) {
accNode.sub_items.push(curr);
} else {
acc.push({
title: curr.type,
sub_items: [curr],
});
}
} else {
acc.push(curr);
}
return acc;
}, []);
console.log(output);
I am trying to make a function that maps the data2 object value to the name of the data1.
I tried to iterate data2 object2 with data1 but it is not working properly. I am able to map them but not getting the value of data1 when it is not there in data2.
Is there any way I can map properly to get the desired output mentioned in the code?
let data1 = {
attributes: [{
Id: 'test1',
Name: 'Test1',
Type: 'date'
},
{
Id: 'test2',
Name: 'Test2',
Type: 'string'
},
{
Id: 'test3',
Name: 'Test3',
Type: 'string'
},
{
Id: 'test4',
Name: 'Test4',
Type: 'boolean'
}
]
};
let data2 = {
value: [{
test1: '10-12-2021',
test2: '4',
dummy: 'ignore me'
},
{
test3: '3',
test4: true,
abc: 'ignore me'
},
{
test1: '12-12-2023',
test3: '42',
dummy1: 'ignore me'
}
]
};
//output
let ouput = {
rows: [{
Test1: '10/12/2021',
Test2: '4',
Test3: '',
Test4: ''
},
{
Test1: '',
Test2: '',
Test3: '3',
Test4: 'Y'
},
{
Test1: '12/12/2023',
Test2: '',
Test3: '42',
Test4: ''
}
]
};
//function
function mapper(data1, data2) {
let formattedValue = [];
data2.value.forEach(val => {
let data = {};
for (let prop in val) {
let name;
const filter = data1.attributes.filter(el => el.Id === prop)[0];
if (filter) {
name = filter.Name;
switch (filter.Type) {
case 'boolean':
data[name] =
val[prop] === true ? 'Y' : val[prop] === false ? 'N' : '';
break;
case 'date':
data[name] = new Date(val[prop]).toLocaleDateString();
break;
default:
data[name] = val[prop];
break;
}
}
}
formattedValue.push(data);
});
return formattedValue;
}
console.log(mapper(data1, data2));
same if I pass data2 as empty value I am looking to get below output
let data1 = {
attributes: [
{
Id: 'test1',
Name: 'Test1',
Type: 'string'
},
{
Id: 'test2',
Name: 'Test2',
Type: 'string'
},
{
Id: 'test3',
Name: 'Test3',
Type: 'string'
},
{
Id: 'test4',
Name: 'Test4',
Type: 'boolean'
}
]
};
let data2 = {
value: [
]
};
//output
let ouput = {
rows: [
{
Test1: '',
Test2: '',
Test3: '',
Test4: ''
},
]
};
const data1 = {attributes:[{Id:'test1',Name:'Test1',Type:'date'},{Id:'test2',Name:'Test2',Type:'string'},{Id:'test3',Name:'Test3',Type:'string'},{Id:'test4',Name:'Test4',Type:'boolean'}]}
data2 = {value:[{test1:'10-12-2021',test2:'4'},{test3:'3',test4:true},{test1:'12-12-2023',test3:'42'}]};
data3 = {value: []}
const mapper = (x, y) => {
const row = x.attributes.map(e => [e.Id, e.Name])
format = e => { switch (true) {
case typeof e === 'boolean':
return e ? 'Y' : 'N'
case isNaN(e) && !isNaN(Date.parse(e)):
return new Date(e).toLocaleDateString()
default: return e
}}
const rows = (y.value.length ? y.value : [1]).map(e =>
Object.fromEntries(row.map(([k, v]) => [v, format(e[k]) ?? '']))
)
return { rows }
}
console.log(mapper(data1, data2))
console.log(mapper(data1, data3))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Explanation:
y.value.length ? y.value : [1]
Checks if data.value is empty, if not returns data.value. If yes returns array with 1 element (can be any value, it is just needed to do 1 iteration to meet your requirement about empty data, so value doesn't really matter here.
Rest of code should be pretty clear, if not, let me know.
UPDATE
because you want minimum one set of values even data2.values is empty. My already given solution will work if we add empty object when array is empty, so adding below will fix it.
// I had to add below lines to get your desired result
// if `data2.value` is empty array
const arrayToLoop = [...data2.value];
if(arrayToLoop.length === 0) {
arrayToLoop.push({});
}
and now we will loop variable arrayToLoop rather than data2.value
also wrote small function used to convert the value as per given type, you can extend it as per your own need
function parseValue(type, value){
if(value.length==0){
return '';
}
switch(type.toLowerCase()){
case 'boolean':
return value === true ? 'Y' : value === false ? 'N' : '';
case 'date':
return new Date(value).toLocaleDateString();
default:
return value;
}
}
first I will get all the key and label mapping, and will look all the values for each key.
notice how I done below.
let me know if you face any prob.
function parseValue(type, value){
if(value.length==0){
return '';
}
switch(type.toLowerCase()){
case 'boolean':
return value === true ? 'Y' : value === false ? 'N' : '';
case 'date':
return new Date(value).toLocaleDateString();
default:
return value;
}
}
function BusinessObjectMapper(data1, data2){
const arrayToLoop = [...data2.value];
if(arrayToLoop.length === 0) {
arrayToLoop.push({});
}
const rows = arrayToLoop.map(v=>{
let r = {};
data1.attributes.forEach(o=>{
let {Id, Name, Type} = o;
r[Name]=parseValue(Type, v[Id]||'');
})
return r;
})
return {
rows
};
}
let data1 = {
attributes: [
{
Id: 'test1',
Name: 'Test1',
Type:'string'
},
{
Id: 'test2',
Name: 'Test2',
Type:'boolean',
},
{
Id: 'test3',
Name: 'Test3',
Type:'date'
},
{
Id: 'test4',
Name: 'Test4',
Type:'un-known',
}
]
};
let data2 = {
value: [
{
test1: '1',
test2: true
},
{
test3: '02/02/2020',
test4: '42'
},
{
test1: 'deepak',
test3: '01/01/2021'
}
]
};
let data2_empty = {
value: []
}
console.log(BusinessObjectMapper(data1, data2));
console.log(BusinessObjectMapper(data1, data2_empty));
I solved the object type problem by using the spread operator and Array.prototype.reduce().
const data1 = {
attributes: [
{
Id: "test1",
Name: "Test1",
Type: "date",
},
{
Id: "test2",
Name: "Test2",
Type: "string",
},
{
Id: "test3",
Name: "Test3",
Type: "string",
},
{
Id: "test4",
Name: "Test4",
Type: "boolean",
},
],
};
const data2 = {
value: [
{
test1: "10-12-2021",
test2: "4",
},
{
test3: "3",
test4: true,
},
{
test1: "12-12-2023",
test3: "42",
},
],
};
//function
const data11 = {
attributes: [
{
Id: "test1",
Name: "Test1",
Type: "string",
},
{
Id: "test2",
Name: "Test2",
Type: "string",
},
{
Id: "test3",
Name: "Test3",
Type: "string",
},
{
Id: "test4",
Name: "Test4",
Type: "boolean",
},
],
};
const data12 = {
value: [],
};
function mapper(data1, data2) {
const columns = data1.attributes.reduce((prev, item) => {
prev[item["Id"]] = item;
return prev;
}, {});
const emptyValues = Object.keys(columns).reduce((prev, item) => {
prev[columns[item].Name] = "";
return prev;
}, {});
const getValueByType = (key, v) => {
switch (columns[key].Type) {
case "boolean":
return v ? "Y" : "N";
case "date":
return new Date(v).toLocaleDateString();
default:
return v;
}
};
return {
rows:
(data2.value &&
(data2.value.length == 0
? [emptyValues]
: data2.value.map((row) =>
Object.entries(row).reduce(
(rlt, [key, v]) => {
rlt[columns[key].Name] = getValueByType(key, v);
return rlt;
},
{ ...emptyValues }
)
))) ||
[],
};
}
const result1 = mapper(data1, data2);
console.log(result1.rows);
const result2 = mapper(data11, data12);
console.log(result2);
#ulou's answer is great!. It can be done using reduce. I updated a source a little.
const mapper = (arr1, arr2) => {
const keys = arr1.attributes.map(item => ({ Id: item.Id, Name: item.Name }));
const format = e => {
switch (true) {
case typeof e === 'boolean': return e ? 'Y' : 'N'
case isNaN(e) && !isNaN(Date.parse(e)):
return new Date(e).toLocaleDateString()
default: return e
}
}
const mapped = (arr2.value ?? [0]).map(item => keys.reduce((prev, cur) => (
{ ...prev, [cur.Name]: format(item[cur.Id] ?? '') }
), {}));
return { rows: mapped };
}
console.log(mapper(data1, data2));
console.log(mapper(data1, []));
Is there a way to compare these 2 objects based on topicID and items->item->id and return true for being same? (it must ignore unique element)
const var1 = [
{
unique: "8123456",
topicID: "1234",
items: {
item: [
{
id: "x",
},
{
id: "y",
},
],
},
},
{
unique: "123456",
topicID: "123",
items: {
item: [
{
id: "b",
},
{
id: "a",
},
],
},
},
];
const var2 = [
{
unique: "3123456",
topicID: "123",
items: {
item: [
{
id: "a",
},
{
id: "b",
},
],
},
},
{
unique: "2123456",
topicID: "1234",
items: {
item: [
{
id: "y",
},
{
id: "x",
},
],
},
},
];
a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal"}, { value:"a63a6f77-c637-454e-abf2-dfb9b543af6c", display:"Ryan"}]
b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer", $$hashKey:"008"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed", $$hashKey:"009"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi", $$hashKey:"00A"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal", $$hashKey:"00B"}]
function comparer(otherArray){
return function(current){
return otherArray.filter(function(other){
return other.value == current.value && other.display == current.display
}).length == 0;
}
}
var onlyInA = a.filter(comparer(b));
var onlyInB = b.filter(comparer(a));
result = onlyInA.concat(onlyInB);
console.log(result);
Here is put your required data and use this code you will get success
Try using:
const var1 = [
{
unique: "8123456",
topicID: "1234",
items: {
item: [
{
id: "x",
},
{
id: "y",
},
],
},
},
{
unique: "123456",
topicID: "123",
items: {
item: [
{
id: "b",
},
{
id: "a",
},
],
},
},
];
const var2 = [
{
unique: "3123456",
topicID: "123",
items: {
item: [
{
id: "a",
},
{
id: "b",
},
],
},
},
{
unique: "2123456",
topicID: "1234",
items: {
item: [
{
id: "y",
},
{
id: "x",
},
],
},
},
];
const var3 = [
{
unique: "8123456",
topicID: "1234",
items: {
item: [
{
id: "x",
},
{
id: "y",
},
],
},
},
{
unique: "123456",
topicID: "123",
items: {
item: [
{
id: "b",
},
{
id: "a",
},
],
},
},
];
function objCompare(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (const key of keys1) {
const val1 = object1[key];
const val2 = object2[key];
const isObj= checkObj(val1) && checkObj(val2);
if (
isObj && !objCompare(val1, val2) ||
!isObj && val1 !== val2
) {
return false;
}
}
return true;
}
function checkObj(object) {
return object != null && typeof object === 'object';
}
console.log(objCompare(var1,var2));
console.log(objCompare(var1,var3));
Hope this helps !!!
Without knowing the exact use case, I'll outline a general idea of how you could go about it.
For each item in the array, generate a key based on the topicID and the concatenation of the id within items. From there, you construct a set of both lots of keys, then compare them. This would work assuming that:
There are no duplicates in a single array.
You only need to test for "equality". If you need to pull out the duplicated items it's more difficult, but the same approach can be followed.
const constructKey = o =>
`${o.topicID}_${o.items.item.map(item => item.id).join('')}`
const setEq = (a, b) => a.size === b.size && [...a].every(v => b.has(v));
const var1Keys = new Set(var1.map(constructKey));
const var2Keys = new Set(var2.map(constructKey));
console.log(setEq(var1Keys, var2Keys))
EDIT: Based on your comment, it seems as though you want to compare items regardless of order. Something like this:
const constructMap = (arr) =>
arr.reduce(
(map, { topicID, items }) =>
map.set(topicID, new Set(items.item.map(({ id }) => id))),
new Map(),
)
const setEq = (a, b) => a.size === b.size && [...a].every((v) => b.has(v))
const mapEq = (a, b) =>
a.size === b.size &&
[...a.entries()].every(([k, v]) => b.has(k) && setEq(v, b.get(k)))
const var1Map = constructMap(var1)
const var2Map = constructMap(var2)
console.log(mapEq(var1Map, var2Map))
I have the following:
const itemsArr = [{
id: 0,
baseDetails: {
modelNames: ["Atoga3"],
companies: ['Sunafga']
}
},
{
id: 1,
baseDetails: {
modelNames: ["Bisuda-X23", "Oidas"],
companies: ["Sunafga", "Kemaite"]
}
},
{
id: 2,
baseDetails: {
modelNames: ["Zarusa-M3", "Kalasi-W"],
companies: ["Abado", "Sunafga"]
}
}
]
What I want to achieve is to have an array with each company -> modelName combination.
So it should look like :
[{
value: 'sunafga',
label: 'Sunafga',
children: [{
value: 'atoga3',
label: 'Atoga3'
},
{
value: 'bisuda-x23',
label: 'bisuda-X23'
},
{
value: 'oidas',
label: 'Oidas'
},
{
value: 'zarusa-m3',
label: 'Zarusa-M3'
},
{
value: 'valasi-W',
label: 'Kalasi-W'
}
]
},
{
value: 'kemaite',
label: 'Kemaite',
children: [{
value: 'bisuda-x23',
label: 'bisuda-X23'
},
{
value: 'oidas',
label: 'Oidas'
},
]
},
]
you probably want a two step transform here, one to a useful structure to remove all those dups, then just nudge that into your desired structure
const itemsArr = [{
id: 0,
baseDetails: {
modelNames: ["Atoga3"],
companies: ['Sunafga']
}
},
{
id: 1,
baseDetails: {
modelNames: ["Bisuda-X23", "Oidas"],
companies: ["Sunafga", "Kemaite"]
}
},
{
id: 2,
baseDetails: {
modelNames: ["Zarusa-M3", "Kalasi-W"],
companies: ["Abado", "Sunafga"]
}
}
]
// transform to a useful structure for removing duplicates
const companyMap = itemsArr.reduce((acc, val) => {
val.baseDetails.companies.forEach(c => {
acc[c] = val.baseDetails.modelNames.reduce((a, m) => Object.assign(a, {[m]: true}), (acc[c] || {}))
});
return acc
}, {})
// transform your useful structure to the desired one
const newArray = Object.entries(companyMap).map(([company, models]) => {
return {
value: company.toLowerCase(),
label: company,
children: Object.keys(models).map(model => ({label: model, value: model.toLowerCase()}))
}
})
console.log(newArray)
you could use this if you want as your intermediary transform if you want to reduce all the way down:
const companyMap = itemsArr.reduce((cMap, item) =>
Object.assign(cMap,
item.baseDetails.companies.reduce((iMap, c) =>
Object.assign(iMap,
{[c]: item.baseDetails.modelNames.reduce((a, m) => Object.assign(a, {[m]: true}), (cMap[c] || {}))}
)
, {})
)
, {})
Here's a solution if using reduce isn't mandatory:
const itemsArr = [{
id: 0,
baseDetails: {
modelNames: ["Atoga3"],
companies: ['Sunafga']
}
},
{
id: 1,
baseDetails: {
modelNames: ["Bisuda-X23", "Oidas"],
companies: ["Sunafga", "Kemaite"]
}
},
{
id: 2,
baseDetails: {
modelNames: ["Zarusa-M3", "Kalasi-W"],
companies: ["Abado", "Sunafga"]
}
}
];
const result = [];
itemsArr.forEach(item => {
item.baseDetails.companies.forEach(company => {
let companyEntry = result.find(resultEntry => resultEntry.label === company);
if (!companyEntry) {
companyEntry = {
label: company,
value: company.toLowerCase(),
children: []
};
result.push(companyEntry);
}
const companyChildren = companyEntry.children;
item.baseDetails.modelNames.forEach(modelName => {
if (!companyChildren.find(companyModel => companyModel.label === modelName)) {
companyChildren.push({
label: modelName,
value: modelName.toLowerCase()
});
}
});
});
});
console.log(result);
Sorry for the bad question title, couldn't figure a better one.
I have this array of options:
const options = [
{
display_name: "Size",
_id: "1",
values: [
{
label: "Small",
_id: "1"
},
{
label: "Extra Large",
_id: "2"
}
]
},
{
display_name: "Colors",
_id: "2",
values: [
{
label: "Red",
value: "#ff0000",
_id: "3"
},
{
label: "Green",
value: "#00ff21",
_id: "4"
},
]
}
];
I run this function against it to get Cartesian Product:
const getCartesian = object => {
return Object.entries(object).reduce(
(r, [key, value]) => {
let temp = [];
r.forEach(s =>
(Array.isArray(value) ? value : [value]).forEach(w =>
(w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [key]: x }))
)
)
);
return temp;
},
[{}]
);
};
This will result in an array of objects in the following format (console.log output):
[{0: Object, 1: Object}, {0: Object, 1: Object}, ...]
The desired output is:
[
{
"option":{
"id":1,
"display_name":"Size"
},
"value":{
"label":"Small",
"id": 1
}
},
{
"option":{
"id":2,
"display_name":"Color",
},
"value":{
"id":5,
"label":"Red"
}
}
...
]
here's the playground and what I've tried so far: https://codesandbox.io/s/8nvwm76nnj
You need to map() at the end to convert array to object.
const options = [
{
display_name: "Size",
_id: "1",
values: [
{
label: "Small",
_id: "1"
},
{
label: "Extra Large",
_id: "2"
}
]
},
{
display_name: "Colors",
_id: "2",
values: [
{
label: "Red",
value: "#ff0000",
_id: "3"
},
{
label: "Green",
value: "#00ff21",
_id: "4"
},
]
}
];
const getCartesian = object => {
let t = Object.entries(object).reduce(
(r, [key, value]) => {
let temp = [];
r.forEach(s =>
(Array.isArray(value) ? value : [value]).forEach(w =>
(w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [key]: x }))
)
)
);
return temp;
},
[{}]
);
return t.map(({0:val1,1:val2}) => ({option:val1,arr:val2}))
};
console.log(getCartesian(options));
You could wrap the array in an object with a property option. This gives you later an array with objects with option as key for the cartesian product.
const getCartesian = object => {
return Object.entries(object).reduce(
(r, [key, value]) => {
let temp = [];
r.forEach(s =>
(Array.isArray(value) ? value : [value]).forEach(w =>
(w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [key]: x }))
)
)
);
return temp;
},
[{}]
);
};
const options = [{ display_name: "Size", _id: "1", values: [{ label: "Small", _id: "1" }, { label: "Extra Large", _id: "2" }] }, { display_name: "Colors", _id: "2", values: [{ label: "Red", value: "#ff0000", _id: "3" }, { label: "Green", value: "#00ff21", _id: "4" }] }];
console.log(getCartesian({ option: options }));
.as-console-wrapper { max-height: 100% !important; top: 0; }