Reputation:
The given object of objects to assign an id
to each letter and sort sets (a set is an inner object) of them at once:
const obj = {
0: {0: "X", 1: "B", 2: "C"},
1: {3: "A", 4: "F", 5: "N"},
2: {6: "S", 7: "B", 8: "X"},
3: {9: "B"},
4: {10: "B", 11: "Y"},
};
The given array of letters for instance:
const letters = ['A', 'X', 'B'];
I want the id
of the first occurrence of each letter in the obj
with conditions:
Once we select an id
of a letter in a set (in an inner object), we can only select the next letter from the proceeding sets, not the current set and not the sets before.
So for the given letters array, the result would be:
[3, 8, 9]
Note: letters inside each set are unique.
I can iterate through objects but when it comes to the condition I can't find a proper solution...
Upvotes: 1
Views: 302
Reputation: 1917
You can do it like this, getting the entries of each key and searching for the letter there.
const obj = {0: {0: "X", 1: "B", 2: "C"},1: {3: "A", 4: "F", 5: "N"},2: {6: "S", 7: "B", 8: "X"},3: {9: "B"},4: {10: "B", 11: "Y"},};
const obj2 = { 0: {0: "X", 1: "B", 2: "C"}, 1: {3: "A", 4: "X", 5: "N"}, 2: {6: "S", 7: "B", 8: "X"}, 3: {9: "B"}, 4: {10: "B", 11: "Y"}, };
const fn = (o) => {
const letters = ['A','X','B'];
return Object
.values(o)
.map(Object.entries)
// Find the first occurance and remove it from the letters array
.map((subarray) => subarray.find(([key, value]) => letters[0] === value && letters.shift()))
// Filter undefined values
.filter(Boolean)
// Extract the key
.map(([key]) => key);
};
console.log(fn(obj));
console.log(fn(obj2));
Upvotes: 0
Reputation: 386680
You could take an helper array with all key/value pairs and map the keys.
const
obj = { 0: { 0: "X", 1: "B", 2: "C" }, 1: { 3: "A", 4: "X", 5: "N" }, 2: { 6: "S", 7: "B", 8: "X" }, 3: { 9: "B" }, 4: { 10: "B", 11: "Y" } },
letters = ['A', 'X', 'B'],
helper = Object.values(obj).map(Object.entries),
result = letters.map((i => c => {
let r;
while (!(r = helper[i++ % helper.length].find(a => a[1] === c)));
return +r[0];
})(0));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 769
Since we can only select the next letter from the proceeding sets, we should use an array (objArr
) instead of using an object (obj
) in order to preserve the order of sets.
Also, once found, we should stop looking in the current set and proceed to next letter and set (if present).
The following should handle all these cases while saving unnecessary iterations:
const objArr = [
{0: "X", 1: "B", 2: "C"},
{3: "A", 4: "F", 5: "N"},
{6: "S", 7: "B", 8: "X"},
{9: "B"},
{10: "B", 11: "Y"}
];
const letters = ['A','X','B'];
let setIndex = 0, result = [];
for (let i=0; i< letters.length; i++) {
for (let j=setIndex; j < objArr.length; j++) {
if (Object.values(objArr[j]).includes(letters[i])) {
for (const key in objArr[j]) {
if (objArr[j][key] === letters[i]) {
result.push(key);
setIndex = j+1;
break;
}
}
break;
}
}
}
console.log(result);
Upvotes: 0
Reputation: 488
const obj = {
0: {0: "X", 1: "B", 2: "C"},
1: {3: "A", 4: "F", 5: "N"},
2: {6: "S", 7: "B", 8: "X"},
3: {9: "B"},
4: {10: "B", 11: "Y"},
};
const result = []
const letters = ['A','X','B']
let start = 0
Object.keys(obj).forEach(e=>{
Object.keys(obj[e]).forEach(f=>{
if(obj[e][f] == letters[start]){
result.push(f)
start++
}
})
})
console.log(result)
Upvotes: 0