用javascript中的值返回所有深层对象的嵌套键的好方法

时间:2018-10-29 11:41:37

标签: javascript algorithm object data-structures

我需要访问并返回对象中所有深度嵌套的键,然后根据键返回它们。

例如我有

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'
        }
      ]
    }
  }
}

我需要类似getAllValuesForKey(chatSettings, 'key')之类的东西,它将返回['firstname', 'lastname', 'email']

有什么想法如何以一种高效的方式做到这一点,同时还要考虑到某些对象甚至可能没有此键?

3 个答案:

答案 0 :(得分:1)

您可以使用reduce方法创建递归函数并返回数组。

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'))

答案 1 :(得分:0)

您可以对类型检查使用递归函数并减少对象。

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

答案 2 :(得分:0)

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'))