2

I want to return an object containing only the keys which are passed via an array, For e.g., I have an array of keys,

const arr = ['a', 'b', 'c', 'd', 'e']

and an Object,

const obj = {
    a: {
        name: 'a',
        capital: 'A'
    },
    g: {
        name: 'g',
        capital: 'G'
    },
    b: {
        name: 'b',
        capital: 'B'
    },
    m: {
        c: {
            name: 'c',
            capital: 'C'
        }
    },
    z: {
        name: 'z',
        capital: 'Z'
    },
    n: {
        e: {
            name: 'e',
            capital: 'E'
        }
    },
    o: {
      f: {
        d: {
          name: 'd',
          capital: 'D'
        }
      }
    }
}

Now I want to return an Object which contains just the keys present in arr, 'a', 'b', 'c', 'd' and 'e', so my resultant object will be,

{
    a: {
        name: 'a',
        capital: 'A'
    },
    b: {
        name: 'b',
        capital: 'B'
    },
    c: {
        name: 'c',
        capital: 'C'
    },
    e: {
        name: 'e',
        capital: 'E'
    },
    d: {
        name: 'd',
        capital: 'D'
    }

}

Approach:

I am approaching it like as shown below, but not getting the desired result,

function fetchValueByKey(object, key, result) {
  if(typeof object !== 'object')
    return result;
  for(let objKey in object) {
    if(key.indexOf(objKey) > -1) {
      result[objKey] = object[objKey];
      console.log(result);
    } else {
      result[objKey] = fetchValueByKey(object[objKey], key, result);
      console.log(result)
    }
  }
}

console.log(fetchValueByKey(obj, arr, {}));

Please suggest me on how can I achieve this?

5
  • is name property always the object with the same key? Commented May 11, 2022 at 16:48
  • @NinaScholz No, it can be different Commented May 11, 2022 at 16:49
  • you need to search the keys any number of layers deep? Commented May 11, 2022 at 16:51
  • @hamobi Yes, the key can be deeply nested Commented May 11, 2022 at 16:53
  • what if you have f in the wanted array? Commented May 11, 2022 at 17:36

4 Answers 4

3

Your code is good; you just need to return or output result after the loop. PLUS, there's no need for result[objKey] = since you've already determined that objKey is not in the list of keys you're looking for, so just call the function again to drill down the sub-object.

const arr = ['a', 'b', 'c', 'd', 'e']
const obj = { a: { name: 'a', capital: 'A' }, g: { name: 'g', capital: 'G' }, b: { name: 'b', capital: 'B' }, m: { c: { name: 'c', capital: 'C' } }, z: { name: 'z', capital: 'Z' }, n: { e: { name: 'e', capital: 'E' } }, o: { f: { d: { name: 'd', capital: 'D' } } } };

function fetchValueByKey(object, key, result) {
  if(typeof object !== 'object')
    return result;
  for(let objKey in object) {
    if(key.indexOf(objKey) > -1) {
      result[objKey] = object[objKey];
      //console.log(result);
    } else {
      fetchValueByKey(object[objKey], key, result);
      //console.log(result)
    }
  }
  return result;
}

console.log(fetchValueByKey(obj, arr, {}));

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, got it. Thanks a lot for pointing out my error, really appreciate it :)
2

You could get flat and filterd entries and build an object.

const
    getFlatFilteredEntries = object => Object
        .entries(object)
        .flatMap(([k, v]) => 'name' in v // or other indicator of leaf object
            ? keys.includes(k)
                ? [[k, v]]
                : []
            : getFlatFilteredEntries(v)
        ),
    keys = ['a', 'b', 'c', 'd', 'e'],
    object = { a: { name: 'a', capital: 'A' }, g: { name: 'g', capital: 'G' }, b: { name: 'b', capital: 'B' }, m: { c: { name: 'c', capital: 'C' } }, z: { name: 'z', capital: 'Z' }, n: { e: { name: 'e', capital: 'E' } }, o: { f: { d: { name: 'd', capital: 'D' } } } },
    result = Object.fromEntries(getFlatFilteredEntries(object));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

We can use JSON.stringify here to iterate over every nested object & we can check for the key is included in the array and add that in the object.

const obj = {
    a: {
        name: 'a',
        capital: 'A'
    },
    g: {
        name: 'g',
        capital: 'G'
    },
    b: {
        name: 'b',
        capital: 'B'
    },
    m: {
        c: {
            name: 'c',
            capital: 'C'
        }
    },
    z: {
        name: 'z',
        capital: 'Z'
    },
    n: {
        e: {
            name: 'e',
            capital: 'E'
        }
    },
    o: {
      f: {
        d: {
          name: 'd',
          capital: 'D'
        }
      }
    }
}
const arr = ['a', 'b', 'c', 'd', 'e'];
function getObjects(arr, obj) {
  const a = {};
  let str = JSON.stringify(obj, (key, value) => {
    if(arr.includes(key)) {
      a[key] = value;
      return value
    }
    return value
  });
  return a;
}

console.log(getObjects(arr, obj));

Solved a similar problem with JSON.stringify is really helpful when playing with objects. What is the efficient way to shallow clone an object using JavaScript?

Comments

-1

Object.keys(obj).filter(Key=>arr.includes(Key)).Map(Key=>obj[Key])

That should work!

PS: zorry for the miss spelling but writing from m'y phone

3 Comments

I think the issue is that in his example the keys can be several layers deep. makes it much more complicated.
filter returns an array. Asker does not want array as output.
Oh ok , Indeed. I red that too quickly ... I'll need to do that on m'y computer if no one senf an answer 'till I Can

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.