递归地展平 deeply-nested objects 和数组的混合

Recursively flatten a deeply-nested mix of objects and arrays

我正在尝试扁平化包含混合内容的数据 object(JavaScript 在 React 应用程序中)。我只需要 object 中每个 parent 和 child 的键;我不一定需要这些值(尽管存在它们不会是 deal-breaker)。

我已经搜索了一个多星期以找到适合我的用例的解决方案,但我尝试过的所有方法都达不到要求,包括 vanilla JavaScript、Lodash、Underscore 和 flat (NPM包)。

在每种情况下,我要么得到一个比我预期的更短的列表(因为我只得到 parents),要么得到一个带点的 fully-flattened object notation-delimitedobjects,对我没用

我知道有很多与此主题相关的问题和答案,但我没有看到与我的用例相匹配的东西,而且我似乎无法解决这个问题。

这是我的数据结构示例:

const sampleData = {
  coyotes: '',
  armadillos: false,
  wombats: [''],
  geckos: 0,
  dogs: {
    beagle: '',
    bulldog: ''
  },
  wolves: [
    {
      type: '',
      color: '',
      range: '',
      status: {
        endangered: true,
        protected: false
      }
    }
  ],
  cats: {}
}

这是我(理想情况下)想要的:

result = {coyotes, armadillos, wombats, geckos, dogs, beagle, bulldog, wolves, type, color, range, status, endangered, protected, cats}

下面是我想调用展平方法的方式:

flattenData(sampleData)

这是我目前的情况:

const flattenData = (obj) =>
      Object.assign(
        {},
        ...(function _flatten (o) {
          return [].concat(...Object.keys(o)
            .map(k =>
              typeof o[k] === 'object' ? _flatten(o[k]) : (Number([k]) !== 0 && { [k]: o[k] })
            )
          )
        }(obj))
      )

...产生:

{
    "coyotes": "",
    "armadillos": false,
    "geckos": 0,
    "beagle": "",
    "bulldog": "",
    "type": "",
    "color": "",
    "range": "",
    "endangered": true,
    "protected": false
}

如您所见,缺少一些 parent(袋熊、狗、狼和地位),并且缺少一个空的 object(猫)。

这不是我写过的最漂亮的代码。不幸的是它确实得到了一切

const flattenData = (data) => {
  let results = [];
  const recursive = (data) => {
    Object.keys(data)
      .map(function (key) {
        results.push(key);
        recursive(data[key]);
        return data[key]; // This doesn't actually do anything...
      });
  }
  recursive(data);
  return results;
};

const value = flattenData(sampleData);

这是一个简单的递归:

const deepKeys = (o) => 
  Array .isArray (o)
    ? o .flatMap (deepKeys)
  : Object (o) === o
    ? Object .entries (o) .flatMap (([k, v]) => [k, ... deepKeys (v)])
  : []

const sampleData = {coyotes: '', armadillos: false, wombats: [''], geckos: 0, dogs: {beagle: '', bulldog: ''}, wolves: [{type: '', color: '', range: '', status: {endangered: true, protected: false}}], cats: {}}

console .log (deepKeys (sampleData))
.as-console-wrapper {max-height: 100% !important; top: 0}

我们需要对数组、对象和其他类型进行一些不同的处理,但每一种都相当简单。