One liner to flatten nested object

2020-02-05 06:24发布

I need to flatten a nested object. Need a one liner. Not sure what the correct term for this process is. I can use pure Javascript or libraries, I particularly like underscore.

I've got ...

{
  a:2,
  b: {
    c:3
  }
}

And I want ...

{
  a:2,
  c:3
}

I've tried ...

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

Which works but I also need this to work ...

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

8条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-02-05 07:20
function flatten(obj: any) {
  return Object.keys(obj).reduce((acc, current) => {
    const key = `${current}`;
    const currentValue = obj[current];
    if (Array.isArray(currentValue) || Object(currentValue) === currentValue) {
      Object.assign(acc, flatten(currentValue));
    } else {
      acc[key] = currentValue;
    }
    return acc;
  }, {});
};

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

console.log(flatten(obj))

Demo https://stackblitz.com/edit/typescript-flatten-json

查看更多
放荡不羁爱自由
3楼-- · 2020-02-05 07:21

I like this code because it's a bit easier to understand.

const data = {
  a: "a",
  b: {
    c: "c",
    d: {
      e: "e",
      f: [
        "g",
        {
          i: "i",
          j: {},
          k: []
        }
      ]
    }
  }
};

function flatten(data: any, response = {}, flatKey = "") {
  for (const [key, value] of Object.entries(data)) {
    const newFlatKey = `${flatKey}${key}`;
    if (typeof value === "object" && value !== null && Object.keys(value).length > 0) {
      flatten(value, response, `${newFlatKey}.`);
    } else {
      if (Array.isArray(response)) {
        response.push({
          [newFlatKey]: value
        });
      } else {
        response[newFlatKey] = value;
      }
    }
  }
  return response;
};

console.log(flatten(data));
console.log(flatten(data, []));

Demo https://stackblitz.com/edit/typescript-flatter

For insinde a typescript class use:

  private flatten(data: any, response = {}, flatKey = ''): any {
    for (const [key, value] of Object.entries(data)) {
      const newFlatKey = `${flatKey}${key}`;
      if (typeof value === 'object' && value !== null && Object.keys(value).length > 0) {
        this.flatten(value, response, `${newFlatKey}.`);
      } else {
        if (Array.isArray(response)) {
          response.push({
            [newFlatKey]: value
          });
        } else {
          response[newFlatKey] = value;
        }
      }
    }
    return response;
  }
查看更多
登录 后发表回答