【问题标题】:Recursion not returning right result递归不返回正确的结果
【发布时间】:2021-10-07 16:37:23
【问题描述】:

我正在处理一个我想转换以下对象结构的问题:

[
    {
        "label": "testType",
        "categories": [
            {
                "label": "testCatType",
                "subCategories": [
                    {
                        "label": "newSubCat",
                        "subSubCategories": [
                            {
                                "label": "newSubSubCat1"
                            },
                            {
                                "label": "newSubSubCat2"
                            },
                            {
                                "label": "newSubSubCat3"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "label": "newType",
        "categories": [
            {
                "label": "newCat10",
                "subCategories": [
                    {
                        "label": "newCatSub1",
                        "subSubCategories": [
                            {
                                "label": "bingo11"
                            },
                            {
                                "label": "bingo12"
                            },
                            {
                                "label": "bingo15"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "label": "displacement",
        "categories": []
    },
    {
        "label": "brush",
        "categories": [
            {
                "label": "blood",
                "subCategories": []
            },
            {
                "label": "damage",
                "subCategories": []
            },
        ]
    }
]

变成这样:

{
    "testType": {
        "testCatType": {
            "newSubCat": {
                "newSubSubCat1": {},
                "newSubSubCat2": {},
                "newSubSubCat3": {}
            }
        }
    },
    "newType": {
        "newCat10": {
            "newCatSub1": {
                "bingo11": {},
                "bingo12": {},
                "bingo15": {}
            }
        }
    },
    "displacement": {},
    ....
}

我为此实现了以下递归解决方案:

recursiveAssign(obj, json) {
    if (_.isUndefined(obj)) {
      return;
    }

    let totalKeys = _.keys(obj);
    return _.assign(json, { [obj['label']]: this.test(obj[totalKeys[1]], json) })
  }

transform(typeObj){
    let json = {};
    _.forEach(typeObj, obj => {
      let totalKeys = _.keys(obj);
      if (totalKeys < 2) {
        _.assign(json, obj['label']);
      } else {
        _.assign(json, { [obj['label']]: this.recursiveAssign(obj[totalKeys[1]], json) })
      }
    })
}

现在的最终结果是一个对象在每个级别上都是其自身的副本,我不太明白问题出在哪里。我认为我的方法没有错误,因为我使用标签并在该对象的另一部分调用递归函数。请有人指出潜在的问题!

【问题讨论】:

  • json 对象太大了,看这个的人基本上是在替你干活。最好把它分解成一个更小的例子。
  • 给你史蒂夫。使物体变小。希望这现在有意义。

标签: javascript recursion multidimensional-array functional-programming


【解决方案1】:

你可以像这样在纯js中解决这个问题:

const arr = [{ "label": "testType", "categories": [{ "label": "testCatType", "subCategories": [{ "label": "newSubCat", "subSubCategories": [{ "label": "newSubSubCat1" }, { "label": "newSubSubCat2" }, { "label": "newSubSubCat3" }] }] }] }, { "label": "newType", "categories": [{ "label": "newCat10", "subCategories": [{ "label": "newCatSub1", "subSubCategories": [{ "label": "bingo11" }, { "label": "bingo12" }, { "label": "bingo15" }] }] }] }, { "label": "displacement", "categories": [] }, { "label": "brush", "categories": [{ "label": "blood", "subCategories": [] }, { "label": "damage", "subCategories": [] }, ] }];

let result = recursive(arr);

console.log(result);

function recursive(arr) {
  let result = {};
  let returnValue = {}
  for (let obj of arr) {
    let entries = Object.entries(obj);
    if (!entries.length) {
      return {};
    }

    for (let [key, value] of entries) {
      if (typeof value == "object") {
        result = recursive(value);
      }
    }

    const label = obj["label"];
    returnValue = { ...returnValue,
      [obj["label"]]: result
    };
  }
  return returnValue;
}
.as-console-wrapper {min-height: 100%;}

【讨论】:

  • 感谢@Harsh 的回答。知道如何在这个递归函数中对 subCategories 和 subSubCategories 进行排序吗?
  • @gameFrenzy07,你能解释一下你在这里排序是什么意思,因为我们不能对对象进行排序吗?
  • 是的,所以我想根据标签属性进行排序。所以说最上面的标签是“刷子”。现在它有另外两个类别“伤害”和“血液”。理想情况下,我希望“血”最终高于“伤害”。
【解决方案2】:

你可以把transform写成一个简单的递归函数-

function transform (all = []) {
  return Object.fromEntries(all.map(t =>
    [t.label, transform(t.categories ?? t.subCategories ?? t.subSubCategories)]
  ))
}

const data =
  [{"label":"testType","categories":[{"label":"testCatType","subCategories":[{"label":"newSubCat","subSubCategories":[{"label":"newSubSubCat1"},{"label":"newSubSubCat2"},{"label":"newSubSubCat3"}]}]}]},{"label":"newType","categories":[{"label":"newCat10","subCategories":[{"label":"newCatSub1","subSubCategories":[{"label":"bingo11"},{"label":"bingo12"},{"label":"bingo15"}]}]}]},{"label":"displacement","categories":[]},{"label":"brush","categories":[{"label":"blood","subCategories":[]},{"label":"damage","subCategories":[]},]}]

console.log(JSON.stringify(transform(data), null, 2))
{
  "testType": {
    "testCatType": {
      "newSubCat": {
        "newSubSubCat1": {},
        "newSubSubCat2": {},
        "newSubSubCat3": {}
      }
    }
  },
  "newType": {
    "newCat10": {
      "newCatSub1": {
        "bingo11": {},
        "bingo12": {},
        "bingo15": {}
      }
    }
  },
  "displacement": {},
  "brush": {
    "blood": {},
    "damage": {}
  }
}

如果需要,您可以链接 ... ?? t.subSubSubCategories... ?? t.subSubSubSubCategories。更好的方法是为图中的所有节点创建一致的节点接口。您可以通过将所有 sub*Categories 重命名为简单的 categories 来实现此目的。这将为每个节点提供一个类似的接口

Node: { label: String, categories: Array<Node> }

【讨论】:

  • 感谢您的回答。语法 "... ?? t.subSubSubCategories, ... ?? t.subSubSubSubCategories" 在这里做什么。这是什么意思?
  • 嗨,那是nullish coalescing operator。如果您有任何其他问题,请告诉我
猜你喜欢
  • 2018-06-20
  • 1970-01-01
  • 2023-01-05
  • 2012-04-11
  • 2016-02-06
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多