简体   繁体   English

递归地展平深度嵌套的对象组合和 arrays

[英]Recursively flatten a deeply-nested mix of objects and arrays

I'm trying to flatten a data object that contains mixed content (JavaScript within a React application).我正在尝试展平包含混合内容(React 应用程序中的 JavaScript)的数据 object。 I just need the keys of every parent and child in the object;我只需要object中每个父母和孩子的钥匙; I don't necessarily need the values (though having them present wouldn't be a deal-breaker).我不一定需要这些值(尽管存在它们不会破坏交易)。

I've searched for over a week to find a solution that would fit my use case, but everything I've tried has fallen short, including vanilla JavaScript, Lodash, Underscore, and flat (NPM package).我已经搜索了一个多星期来找到适合我用例的解决方案,但是我尝试过的所有东西都达不到要求,包括 vanilla JavaScript、Lodash、Underscore 和 flat(NPM 包)。

In every case, I either get a shorter list than I expect (because I'm only getting the parents), or I get a fully-flattened object with dot notation-delimited objects, which is useless to me.在每种情况下,我要么得到一个比我预期的更短的列表(因为我只得到父母),要么得到一个带有点符号分隔对象的完全扁平化的 object,这对我来说没用。

I know there are lots of questions & answers pertaining to this topic, but nothing I've seen matches my use case, and I can't seem to wrap my head around the problem.我知道有很多与该主题相关的问题和答案,但我所看到的没有与我的用例相匹配,而且我似乎无法解决这个问题。

Here is a sample of my data structure:这是我的数据结构的示例:

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

Here is what I (ideally) want back:这是我(理想情况下)想要回来的:

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

Here is the way I'd like to call the flattening method:这是我想调用扁平化方法的方式:

flattenData(sampleData)

Here's what I have so far:这是我到目前为止所拥有的:

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

...which produces: ...产生:

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

As you'll note, some parents are missing (wombats, dogs, wolves and status), and an empty object is missing (cats).如您所见,一些父母不见了(袋熊、狗、狼和地位),并且缺少一个空的 object(猫)。

This isn't the prettiest code I've ever wrote.这不是我写过的最漂亮的代码。 Unfortunately it does get everything不幸的是它确实得到了一切

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

Here's a simple recursion:这是一个简单的递归:

 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}

We need to process a little differently for arrays, objects, and other types, but each one is fairly simple.我们需要对 arrays、对象和其他类型进行一些不同的处理,但每一种都相当简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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