user13849624
user13849624

Reputation:

iterating through object of objects with condition

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

Answers (4)

Alex G
Alex G

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

Nina Scholz
Nina Scholz

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

Kunal Kukreja
Kunal Kukreja

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

Rahul Pal
Rahul Pal

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

Related Questions