一个衬垫来压平嵌套对象

dan*_*y74 12 javascript underscore.js

我需要展平嵌套对象.需要一个班轮.不确定这个过程的正确用语是什么.我可以使用纯Javascript或库,我特别喜欢下划线.

我有 ...

{
  a:2,
  b: {
    c:3
  }
}
Run Code Online (Sandbox Code Playgroud)

而且我要 ...

{
  a:2,
  c:3
}
Run Code Online (Sandbox Code Playgroud)

我试过了 ...

var obj = {"fred":2,"jill":4,"obby":{"john":5}};
var resultObj = _.pick(obj, "fred")
alert(JSON.stringify(resultObj));
Run Code Online (Sandbox Code Playgroud)

哪个有效,但我也需要这个......

var obj = {"fred":2,"jill":4,"obby":{"john":5}};
var resultObj = _.pick(obj, "john")
alert(JSON.stringify(resultObj));
Run Code Online (Sandbox Code Playgroud)

小智 29

干得好:

Object.assign({}, ...function _flatten(o) { return [].concat(...Object.keys(o).map(k => typeof o[k] === 'object' ? _flatten(o[k]) : ({[k]: o[k]})))}(yourObject))
Run Code Online (Sandbox Code Playgroud)

摘要:递归地创建一个属性对象的数组,然后将它们全部组合在一起Object.assign.

这使用ES6功能,包括Object.assign扩展运算符,但它应该很容易重写不要求它们.

对于那些不关心单行疯狂​​而又愿意真正阅读它的人(取决于你对可读性的定义):

Object.assign(
  {}, 
  ...function _flatten(o) { 
    return [].concat(...Object.keys(o)
      .map(k => 
        typeof o[k] === 'object' ?
          _flatten(o[k]) : 
          ({[k]: o[k]})
      )
    );
  }(yourObject)
)
Run Code Online (Sandbox Code Playgroud)

  • 不正确处理null或数组 (5认同)

mur*_*zel 13

这是一个真正的、疯狂的单行代码,它递归地平铺嵌套对象:

const flatten = (obj, roots = [], sep = '.') => Object.keys(obj).reduce((memo, prop) => Object.assign({}, memo, Object.prototype.toString.call(obj[prop]) === '[object Object]' ? flatten(obj[prop], roots.concat([prop])) : {[roots.concat([prop]).join(sep)]: obj[prop]}), {})
Run Code Online (Sandbox Code Playgroud)

多行版本,解释:

// $roots keeps previous parent properties as they will be added as a prefix for each prop.
// $sep is just a preference if you want to seperate nested paths other than dot.
const flatten = (obj, roots = [], sep = '.') => Object
  // find props of given object
  .keys(obj)
  // return an object by iterating props
  .reduce((memo, prop) => Object.assign(
    // create a new object
    {},
    // include previously returned object
    memo,
    Object.prototype.toString.call(obj[prop]) === '[object Object]'
      // keep working if value is an object
      ? flatten(obj[prop], roots.concat([prop]))
      // include current prop and value and prefix prop with the roots
      : {[roots.concat([prop]).join(sep)]: obj[prop]}
  ), {})
Run Code Online (Sandbox Code Playgroud)

一个例子:

const obj = {a: 1, b: 'b', d: {dd: 'Y'}, e: {f: {g: 'g'}}}
const flat = flatten(obj)
{
  'a': 1, 
  'b': 'b', 
  'd.dd': 'Y', 
  'e.f.g': 'g'
}
Run Code Online (Sandbox Code Playgroud)

单行快乐!


Web*_*ber 12

简化的可读示例,无依赖性

/**
 * Flatten a multidimensional object
 *
 * For example:
 *   flattenObject({ a: 1, b: { c: 2 } })
 * Returns:
 *   { a: 1, c: 2}
 */
export const flattenObject = (obj) => {
  const flattened = {}

  Object.keys(obj).forEach((key) => {
    if (typeof obj[key] === 'object' && obj[key] !== null) {
      Object.assign(flattened, flattenObject(obj[key]))
    } else {
      flattened[key] = obj[key]
    }
  })

  return flattened
}
Run Code Online (Sandbox Code Playgroud)

工作示例:https : //jsfiddle.net/webbertakken/jn613d8p/2/


met*_*ory 8

ES6 原生,递归:

单线

const crushObj = (obj) => Object.keys(obj).reduce((acc, cur) => typeof obj[cur] === 'object' ? { ...acc, ...crushObj(obj[cur]) } : { ...acc, [cur]: obj[cur] } , {})
Run Code Online (Sandbox Code Playgroud)

扩展

const crushObj = (obj = {}) => Object.keys(obj || {}).reduce((acc, cur) => {
  if (typeof obj[cur] === 'object') {
    acc = { ...acc, ...crushObj(obj[cur])}
  } else { acc[cur] = obj[cur] }
  return acc
}, {})
Run Code Online (Sandbox Code Playgroud)

用法

const obj = {
  a:2,
  b: {
    c:3
  }
}

const crushed = crushObj(obj)
console.log(crushed)
// { a: 2, c: 3 }
Run Code Online (Sandbox Code Playgroud)


And*_*ndy 8

这是一个正确输出数组索引的展平函数。

function flatten(obj) {
  const result = {};
  for (const key of Object.keys(obj)) {
    if (typeof obj[key] === 'object') {
      const nested = flatten(obj[key]);
      for (const nestedKey of Object.keys(nested)) {
        result[`${key}.${nestedKey}`] = nested[nestedKey];
      }
    } else {
      result[key] = obj[key];
    }
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

输入示例:

{
  "first_name": "validations.required",
  "no_middle_name": "validations.required",
  "last_name": "validations.required",
  "dob": "validations.required",
  "citizenship": "validations.required",
  "citizenship_identity": {
    "name": "validations.required",
    "value": "validations.required"
  },
  "address": [
    {
      "country_code": "validations.required",
      "street": "validations.required",
      "city": "validations.required",
      "state": "validations.required",
      "zipcode": "validations.required",
      "start_date": "validations.required",
      "end_date": "validations.required"
    },
    {
      "country_code": "validations.required",
      "street": "validations.required",
      "city": "validations.required",
      "state": "validations.required",
      "zipcode": "validations.required",
      "start_date": "validations.required",
      "end_date": "validations.required"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

示例输出

const flattenedOutput = flatten(inputObj);
Run Code Online (Sandbox Code Playgroud)
{
  "first_name": "validations.required",
  "no_middle_name": "validations.required",
  "last_name": "validations.required",
  "dob": "validations.required",
  "citizenship": "validations.required",
  "citizenship_identity.name": "validations.required",
  "citizenship_identity.value": "validations.required",
  "address.0.country_code": "validations.required",
  "address.0.street": "validations.required",
  "address.0.city": "validations.required",
  "address.0.state": "validations.required",
  "address.0.zipcode": "validations.required",
  "address.0.start_date": "validations.required",
  "address.0.end_date": "validations.required",
  "address.1.country_code": "validations.required",
  "address.1.street": "validations.required",
  "address.1.city": "validations.required",
  "address.1.state": "validations.required",
  "address.1.zipcode": "validations.required",
  "address.1.start_date": "validations.required",
  "address.1.end_date": "validations.required"
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*vic 6

我的ES6版本:

const flatten = (obj) => {
    let res = {};
    for (const [key, value] of Object.entries(obj)) {
        if (typeof value === 'object') {
            res = { ...res, ...flatten(value) };
        } else {
            res[key] = value;
        }
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*ley 5

它不完全是一个衬垫,但这是一个不需要 ES6 任何东西的解决方案。它使用下划线的extend方法,可以将其替换为 jQuery 的方法。

function flatten(obj) {
    var flattenedObj = {};
    Object.keys(obj).forEach(function(key){
        if (typeof obj[key] === 'object') {
            $.extend(flattenedObj, flatten(obj[key]));
        } else {
            flattenedObj[key] = obj[key];
        }
    });
    return flattenedObj;    
}
Run Code Online (Sandbox Code Playgroud)