I'm trying to build a list of all the unique levels in a multidimensional array of objects.
Assuming this data...
let levels = [
["P", "B", "L"],
["A", "B", "L3"],
["A", "B", "L3"],
["P", "B", "M"],
["P", "C", "L"],
["A", "C", "L3"]
];
I need to end up with an array structure like this:
const result = [
[ 1, 'P', 11, 'P.B', 111, 'P.B.L' ],
[ 1, 'P', 11, 'P.B', 112, 'P.B.M' ],
[ 1, 'P', 12, 'P.C', 121, 'P.C.L' ],
[ 2, 'A', 21, 'A.B', 211, 'A.B.L3' ],
[ 2, 'A', 22, 'A.C', 221, 'A.C.L3' ]
];
Note:
Where each entry is an array of a unique level.
Level ids:
1 => level 1
11 => level 1 and its sub level
111 => level 1, its sub level and sub level's level
On each new level 1 the id will increment as follows for other sub-levels and sub level's level:
2 => new level 1
21 => new level 1 and its new sub-level
211 => new level 1, its new sub-level and new sub level's level
I'm having real trouble calculating the level ids for each unique pair. So far I have tried to return the unique pairs only as below:
function updateLevels(levels) {
const { result } = levels.reduce(
(acc, crr) => {
const l1Key = crr[0];
const l2Key = `${l1Key}.${crr[1]}`;
const l3Key = `${l2Key}.${crr[2]}`;
if (!acc.checkMap[l3Key]) {
acc.checkMap[l3Key] = true;
acc.result.push([l1Key, l2Key, l3Key]);
}
return acc;
},
{
checkMap: {},
result: [],
}
);
return result;
}
const result =
[
[ 'P', 'P.B', 'P.B.L' ],
[ 'A', 'A.B', 'A.B.L3' ],
[ 'P', 'P.B', 'P.B.M' ],
[ 'P', 'P.C', 'P.C.L' ],
[ 'A', 'A.C', 'A.C.L3' ]
]
Basically this solution needs two steps:
Get an array with numbers and connected strings.
You could take an object for keeping the level information and check if the actual data set exists with a flag add for pushing a new array to the result set.
Sort the result by taking odd indices of the array.
const
getUnique = array => {
const levels = { _: 0, data: [] };
return array
.reduce((r, a) => {
let add = false;
const
temp = [],
final = a.reduce((l, v, i, a) => {
if (!l[v]) {
l[v] = {
_: 0,
data: [(l.data[0] || 0) * 10 + ++l._, (l.data[1] || '' ) + (l.data[1] ? '.' : '') + v]
};
add = true;
}
temp.push(...l[v].data);
return l[v];
}, levels);
if (add) r.push(temp);
return r;
}, [])
.sort((a, b) => {
let i = 0, r = 0;
while (i < a.length && !r) {
r = a[i] - b[i];
i += 2;
}
return r;
});
},
levels = [["P", "B", "L"], ["A", "B", "L3"], ["A", "B", "L3"], ["P", "B", "M"], ["P", "C", "L"], ["A", "C", "L3"]],
result = getUnique(levels);
result.forEach(a => console.log(...a));