简体   繁体   中英

good way to return all deeply object's nested keys with values in javascript

I need to access and return all deeply nested key's in an object and return them based on a key.

For example I have

const chatSettings = {
  name: {
    questions: {
      question: 'What\'s your name?',
      fields: [
        {
          field: 'textinput',
          type: 'text',
          key: 'firstname',
          label: 'First name'
        },
        {
          field: 'textinput',
          type: 'text',
          key: 'lastname',
          label: 'Last name'
        },
      ]
    }
  },
  email: {
    questions: {
      question: 'Okay. {{username}}. Now type your email addess',
      fields: [
        {
          field: 'textinput',
          type: 'email',
          key: 'email',
          label: 'Email'
        }
      ]
    }
  }
}

And I need something like, getAllValuesForKey(chatSettings, 'key') , which would return ['firstname', 'lastname', 'email']

Any ideas how to do it in a performant way while as well taking into account that some of these objects might not even have this key?

You could create recursive function with reduce method and return array as a result.

 const data = {"name":{"questions":{"question":"What's your name?","fields":[{"field":"textinput","type":"text","key":"firstname","label":"First name"},{"field":"textinput","type":"text","key":"lastname","label":"Last name"}]}},"email":{"questions":{"question":"Okay. {{username}}. Now type your email addess","fields":[{"field":"textinput","type":"email","key":"email","label":"Email"}]}}} function find_deep(data, key) { return Object.keys(data).reduce((r, e) => { if (typeof data[e] == 'object') r.push(...find_deep(data[e], key)) if (key == e) r.push(data[e]) return r }, []) } console.log(find_deep(data, 'key')) 

You could use a recursive function with a type check and reduce the object.

 function getValues(object, key) { return object && typeof object === 'object' ? Object .entries(object) .reduce((r, [k, v]) => r.concat(k === key ? v : getValues(v, key)), []) : []; } var chatSettings = { name: { questions: { question: 'What\\'s your name?', fields: [{ field: 'textinput', type: 'text', key: 'firstname', label: 'First name' }, { field: 'textinput', type: 'text', key: 'lastname', label: 'Last name' },] } }, email: { questions: { question: 'Okay. {{username}}. Now type your email addess', fields: [{ field: 'textinput', type: 'email', key: 'email', label: 'Email' }] } } }, values = getValues(chatSettings, 'key'); console.log(values); 

 const chatSettings = { name: { questions: { question: 'What\\'s your name?', fields: [ { field: 'textinput', type: 'text', key: 'firstname', label: 'First name' }, { field: 'textinput', type: 'text', key: 'lastname', label: 'Last name' }, ] } }, email: { questions: { question: 'Okay. {{username}}. Now type your email addess', fields: [ { field: 'textinput', type: 'email', key: 'email', label: 'Email' } ] } } } function getAllValuesByKey(obj, key) { let values = [] if(Array.isArray(obj)) { obj.forEach(o => { let value = getAllValuesByKey(o, key) if(value && value.length > 0) { values = values.concat(value) } }) } else if(typeof obj === 'object') { Object.keys(obj).forEach(k => { if(k == key) { values.push(obj[k]) } if(Array.isArray(obj[k]) || typeof obj[k] == 'object') { let value = getAllValuesByKey(obj[k], key) if(value && value.length > 0) { values = values.concat(value) } } }) } return values } console.log(getAllValuesByKey(chatSettings, 'key')) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM