Home > Software engineering >  if object has key from different array object key value, return only that key
if object has key from different array object key value, return only that key

Time:03-28

I have 2 arrays.

One array contains some people objects, the other array contains objects with name key that holds the value needed from the people objects.

My solution so far but not getting any luck....

When mapping over people array how do I return only certain properties from person? Not the entire person object

const customContactValues = people.map((person) => { return valuesNeeded.filter((el) => (el.name in person) ? person[el.name] : ""  ) })

console.log(customContactValues)

Here is my people array

    const people = [
    {
        "foods": {
            "favoriteFood": "Ice cream"
        },
        "firstName": "John",
        "lastName": "Doe",
        "age": 30

    },
    {
        "foods": {
            "favoriteFood": "pizza"
        },
        "firstName": "Jane",
        "lastName": "Doe",
        "age": 39
    },
    {
        "foods": {
            "favoriteFood": "pbj"
        },
        "firstName": "Kevin",
        "lastName": "Baker",
        "age": 22

    },
    {
        "foods": {
            "favoriteFood": "pushpops"
        },
        "firstName": "ernie",
        "lastName": "duncan",
        "age": 29
    },
]

Here is the values array which contains the keys I need from people array

const valuesNeeded = [ 
  { name: 'firstName' },
  { name: 'lastName' },
  { name: 'favoriteFood' }
]

I am trying to get and output like this below

const desiredResult = [
{firstName: "John", lastName: "Doe", favoriteFood: "Ice cream"},
{firstName: "Jane", lastName: "Doe", favoriteFood: "Pizza"},
{firstName: "Kevin", lastName: "Baker", favoriteFood: "pbj"},
{firstName: "ernie", lastName: "duncan", favoriteFood: "pushpops"}
]

CodePudding user response:

filter only filters elements from array based on some condition but in your case we don't want to filter elements we just want to create new array of objects from and existing array so map function is a good start.

Second problem is the object can contain nested object which may contain required key value pair so to retrieve them we can recursively look over the value which is object if we don't find the key value directly in the object.

And since we don't want all the key value for each object in array we can either create a new object or delete from existing object, keeping the original is good and safe option if required for further processing.

const people = [{
    "foods": {
      "favoriteFood": "Ice cream"
    },
    "firstName": "John",
    "lastName": "Doe",
    "age": 30

  },
  {
    "foods": {
      "favoriteFood": "pizza"
    },
    "firstName": "Jane",
    "lastName": "Doe",
    "age": 39
  },
  {
    "foods": {
      "favoriteFood": "pbj"
    },
    "firstName": "Kevin",
    "lastName": "Baker",
    "age": 22

  },
  {
    "foods": {
      "favoriteFood": "pushpops"
    },
    "firstName": "ernie",
    "lastName": "duncan",
    "age": 29
  },
];

// function to retrieve the key value recursively
function valueByKey(obj, key) {
  let value = obj[key];
  if (value) {
    return value;
  }
  Object.keys(obj).forEach(function(k) {
    if (typeof obj[k] == 'object') {
      value = valueByKey(obj[k], key);
    }
  });
  return value;
}

const valuesNeeded = [{
    name: 'firstName'
  },
  {
    name: 'lastName'
  },
  {
    name: 'favoriteFood'
  }
];

// creating new object by passing the current object and key
let output = people.map(function(item) {
  let result = {};
  valuesNeeded.forEach(function(obj) {
    result[obj.name] = valueByKey(item, obj.name);
  });
  return result;
});

console.log(output);

CodePudding user response:

You can search for the desired key on the top level, and go to child objects if not found. Here is my approach :

function getValue(obj, key) {
    const keys = Object.keys(obj);
    // Check if key exist on this level
    if (keys.includes(key)) {
        return obj[key];
    } else {
        // else we try to find in child objects
        for (k of keys) {
            if (typeof obj[k] == 'object') {
                return getValue(obj[k], key);
            }
        }
    }
    //Return this if not found
    return '';
}

const people = [
    {
        foods: {
            favoriteFood: 'Ice cream',
        },
        firstName: 'John',
        lastName: 'Doe',
        age: 30,
    },
    {
        foods: {
            favoriteFood: 'pizza',
        },
        firstName: 'Jane',
        lastName: 'Doe',
        age: 39,
    },
    {
        foods: {
            favoriteFood: 'pbj',
        },
        firstName: 'Kevin',
        lastName: 'Baker',
        age: 22,
    },
    {
        foods: {
            favoriteFood: 'pushpops',
        },
        firstName: 'ernie',
        lastName: 'duncan',
        age: 29,
    },
];

const valuesNeeded = [
    { name: 'firstName' },
    { name: 'lastName' },
    { name: 'favoriteFood' },
];

let output = people.map((item) => {
    let result = {};
    valuesNeeded.forEach(function (obj) {
        result[obj.name] = getValue(item, obj.name);
    });
    return result;
});

console.log(output);

Edit 1 : You can further simplify valuesNeeded to keysNeeded and store only the keys in an array like this keysNeeded = ['firatName', 'lastName', 'favoriteFood']. Please change invocation accordingly.

  • Related