The following returns all arrProps
that have a matching arrValues
value:
const arr = [
{ arrProps: [{name: '1', prop2: 'aaa'}], arrValues: ['apple', 'orange'] },
{ arrProps: [{name: '2', prop2: 'bbb'}], arrValues: ['taco', 'orange' ] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: ['fish', 'apple', 'orange'] }
];
const result = arr
.flatMap(({ arrValues }) => arrValues ) // all values
.filter((value, index, coll) => coll.indexOf(value) === index) //unique values
.reduce((acc, value) => {
const parentProp = arr // name, prop2, arrValues
.filter((obj) => obj.arrValues.includes(value))
.map((obj) => obj.arrProps[0].name);
//.map((obj) => [{ source: obj.arrProps[0].name, value: obj.arrValues[0], sourceID: null}]);
acc[value] = (acc[value] ? [...acc[value], parentProp] : [parentProp])
.join(',');
acc[value] = parentProp
return acc;
}, {})
console.log(result);
console.table(result);
I need to add additional properties to arrValues, thereby using objects rather than values:
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ symbol: 'apple', id: '1.apple' }, {symbol: 'orange', id: '1.orange'}] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ symbol: 'fish', id: '2.fish' }, { symbol: 'pizza', id: '2.pizza' }, { symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ symbol: 'grape', id: '3.grape'}, { symbol: 'apple', id: '3.apple' }] },
];
From simply 'apple'
, I need to add some additional uniquely identifying values, i.e. { symbol: 'apple', id: '1.apple' }
I'm sure it's in here:
aMap.filter((value, index, coll) => coll.indexOf(value) === index) // <--- filter issue
Which is returning the object (previous data model, just the value 'apple', 'orange'...):
Array(7) [Object, Object, Object, Object, Object, Object, Object]
[[Prototype]]: Array(0)
length: 7
0: Object {symbol: "apple", id: "1.apple"}
1: Object {symbol: "orange", id: "1.orange"}
2: Object {symbol: "fish", id: "2.fish"}
3: Object {symbol: "pizza", id: "2.pizza"}
4: Object {symbol: "red", id: "2.red"}
5: Object {symbol: "grape", id: "3.grape"}
6: Object {symbol: "apple", id: "3.apple"}
__proto__: Array(0)
I'm having a heck of a time trying to filter on arrValues[0].symbol
. I then need to append arrValues[0].id
to the results. I figure createing a new object with arrProps and the unique ID would be best.
So in the case of apple
, the first column should render {parent: arrProps[0], id: arrValues[0].id}
, etc.
--- UPDATE ---
Rather than just showing the name of arrPorps[0].name, I need an object returned, as per the last line above (a change from the original question).
I had thought about finding some way to append arrProps to the output but got stuck there. Since I can hydrate the data model, I added some additional identifying properties to arrValues[]
(wait, does this and arrProps[]
really need to be an array, it's just an object - refactor?):
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ exchange: '1', symbol: 'apple', id: '1.apple' }, {exchange: '1', symbol: 'orange', id: '1.orange' }] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ exchange: '2', symbol: 'fish', id: '2.fish' }, { exchange: '2', symbol: 'pizza', id: '2.pizza' }, { exchange: '2', symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ exchange: '3', symbol: 'grape', id: '3.grape' }, { exchange: '3', symbol: 'apple', id: '3.apple' }] },
];
Then changed the output, creating an output object,
From: .map(({ arrProps }) => arrProps[0].name)
To: .map(({ arrValues }) => [{ exchange: arrValues[0].exchange, symbol: arrValues[0].symbol, id: arrValues[0].id }]);
Whole updated code:
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ exchange: '1', symbol: 'apple', id: '1.apple' }, {exchange: '1', symbol: 'orange', id: '1.orange' }] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ exchange: '2', symbol: 'fish', id: '2.fish' }, { exchange: '2', symbol: 'pizza', id: '2.pizza' }, { exchange: '2', symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ exchange: '3', symbol: 'grape', id: '3.grape' }, { exchange: '3', symbol: 'apple', id: '3.apple' }] },
];
const objectValues = arr.flatMap(({ arrValues }) => arrValues); // not necessary if we refactor, removing these arrays?
const values = objectValues.map(({ symbol }) => symbol);
const uniqueValues = [...new Set(values)];
const result = uniqueValues.reduce((acc, value) => {
acc[value] = arr
.filter(({ arrValues }) => {
const symbols = arrValues.map(({ symbol }) => symbol)
return symbols.includes(value);
})
//.map(({ arrProps }) => arrProps[0].name)
.map(({ arrValues }) => [{ exchange: arrValues[0].exchange, symbol: arrValues[0].symbol, id: arrValues[0].id }]);
//.join(',');
return acc;
}, {});
console.log("RAW:" JSON.stringify(result));
console.log(result);
console.table(result);
Object.entries(result).forEach(([k, v]) => {
console.log(` ----] The value '${k}' exists in:`);
console.table(JSON.stringify(v));
//console.log("The pair: ", k)
////console.log("The value: ", v)
v.forEach(_pool => console.log(`
Exchange: ${_pool[0].exchange}
symbol: ${_pool[0].symbol}
ID: ${_pool[0].id}
`));
})
Two problems:
- I think the arrays are not necessary in the data model
- The output data is wrong.
{ "apple":[ [ { "exchange":"1", "symbol":"apple", "id":"1.apple" } ], [ { "exchange":"3", "symbol":"grape", // should be "apple" "id":"3.grape" // should be "3.apple" } ] ], "orange":[ [ { "exchange":"1", "symbol":"apple", // should be "orange" "id":"1.apple" // should be "1.orange" } ] ], "fish":[ [ { "exchange":"2", "symbol":"fish", "id":"2.fish" } ] ], "pizza":[ [ { "exchange":"2", "symbol":"fish", // should be pizza "id":"2.fish" // should be 2.pizza } ] ], "red":[ [ { "exchange":"2", "symbol":"fish", // should be "red" "id":"2.fish" // should be "2.red" } ] ], "grape":[ [ { "exchange":"3", "symbol":"grape", "id":"3.grape" } ] ] }
CodePudding user response:
After several approaches, I changed solution. In my opinion, it is now simpler and more versatile.
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ symbol: 'apple', id: '1.apple' }, {symbol: 'orange', id: '1.orange'}] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ symbol: 'fish', id: '2.fish' }, { symbol: 'pizza', id: '2.pizza' }, { symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ symbol: 'grape', id: '3.grape'}, { symbol: 'apple', id: '3.apple' }] },
];
const result = arr.reduce((acc, { arrProps: [{ name }], arrValues }) => {
arrValues.map(({ symbol }) => symbol)
.forEach((value) => {
acc[value] = acc[value] ? `${acc[value]},${name}`: name;
});
return acc;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If we consider the previous approach with the filter, the solution could be as follows:
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ symbol: 'apple', id: '1.apple' }, {symbol: 'orange', id: '1.orange'}] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ symbol: 'fish', id: '2.fish' }, { symbol: 'pizza', id: '2.pizza' }, { symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ symbol: 'grape', id: '3.grape'}, { symbol: 'apple', id: '3.apple' }] },
];
const objectValues = arr.flatMap(({ arrValues }) => arrValues);
const values = objectValues.map(({ symbol }) => symbol);
const uniqueValues = [...new Set(values)];
const result = uniqueValues.reduce((acc, value) => {
acc[value] = arr
.filter(({ arrValues }) => {
const symbols = arrValues.map(({ symbol }) => symbol)
return symbols.includes(value);
})
.map(({ arrProps }) => arrProps[0].name)
.join(',');
return acc;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
---UPDATE---
const arr = [
{ arrProps: [{ name: '1', prop2: 'aaa' }], arrValues: [{ exchange: '1', symbol: 'apple', id: '1.apple' }, {exchange: '1', symbol: 'orange', id: '1.orange' }] },
{ arrProps: [{ name: '2', prop2: 'bbb' }], arrValues: [{ exchange: '2', symbol: 'fish', id: '2.fish' }, { exchange: '2', symbol: 'pizza', id: '2.pizza' }, { exchange: '2', symbol: 'red', id: '2.red' }] },
{ arrProps: [{ name: '3', prop2: 'ccc' }], arrValues: [{ exchange: '3', symbol: 'grape', id: '3.grape' }, { exchange: '3', symbol: 'apple', id: '3.apple' }] },
];
const result = arr.reduce((acc, { arrValues }) => {
arrValues.forEach((value) => {
acc[value.symbol] = acc[value.symbol]
? [...acc[value.symbol], value]
: [value];
});
return acc;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }