Home > Blockchain >  Filter an object by an array of keys in Javascript
Filter an object by an array of keys in Javascript

Time:05-12

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?

CodePudding user response:

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, {}));

CodePudding user response:

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; }

CodePudding user response:

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?

CodePudding user response:

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

  • Related