我试图遍历object
,以嵌套结构查找总是具有相同名称subProperty
的属性或键。该对象可以在不同级别上拥有一次或多次。
这是我当前的伪代码。
检查obj
是否具有属性subProperty
。
如果没有,请返回false
如果有,请深入一层(obj.subProperty),然后检查其是否具有属性subProperty
,依此类推...
我想做recursively
,但是我无法确定。任何人都可以通过递归函数帮助我检查每个级别是否具有该属性,如果有的话,将true推入数组
const obj = {
level1: 'level 1',
subProperty: {
level2: 'level 2',
subProperty: {
level3: 'level 3'
}
}
}
我正在尝试学习和理解recursion
帮助将不胜感激。
答案 0 :(得分:1)
您可以返回一个带有false
的数组,而不返回subProperty
,否则返回true
和该函数的递归调用结果。
function getLevels({ subProperty }) {
if (subProperty === undefined) return [false];
return [true, ...getLevels(subProperty)];
}
const
object = { level1: 'level 1', subProperty: { level2: 'level 2', subProperty: { level3: 'level 3' } } },
levels = getLevels(object);
console.log(levels);
答案 1 :(得分:0)
我认为所提出的问题并不能真正帮助您学习更多有关递归的知识。根据定义,该函数将始终返回false
(除非您有一个循环对象,该对象可能会不断重复出现,直到堆栈用完。)
因此,我认为这是一个有用的变体:除了返回false
之外,我们还可以返回第一个没有属性subProperty
的嵌套对象。因此,对于您的示例对象,这应该返回对嵌套{level3: 'level 3'}
对象的引用。
由于我们的数据结构显然是递归的,因此这是使用递归解决方案的好地方。这是一种可能性:
const levelWithoutSubProperty = function (obj) {
if ('subProperty' in obj) {
return levelWithoutSubProperty (obj .subProperty)
}
return obj;
}
const obj = {level1: 'level 1', subProperty: {level2: 'level 2', subProperty: {level3: 'level 3'}}}
console .log (
levelWithoutSubProperty (obj) //~> {level3: 'level 3'}
)
这是它的工作方式:
levelWithoutSubProperty({level1: 'level 1', subProperty: {level2: 'level 2', subProperty: {level3: 'level 3'}}})
// `'subProperty' in obj` returns true, so call `levelWithoutSubProperty` with its subProperty:
levelWithoutSubProperty({level2: 'level 2', subProperty: {level3: 'level 3'}})
// `'subProperty' in obj` returns true, so call `levelWithoutSubProperty` with its subProperty:
levelWithoutSubProperty({level3: 'level 3'})
// `'subProperty' in obj` returns false so
return {level3: 'level 3'}
return {level3: 'level 3'}
return {level3: 'level 3'}
直接递归(还有其他类型,但并不复杂)涉及到一个函数,该函数使用从其自身参数以某种方式简化的数据来调用自身。在某些时候,输入必须足够简单,以使您无需再次进行递归调用即可计算结果。这称为基本情况,每个递归函数至少要有一个很重要。否则,该函数将继续无限期地调用自身。
在这里,我们唯一的基本情况是obj
不具有属性subProperty
时,即'subproperty' in obj
返回false时。在这种情况下,我们只需返回提供的参数即可。
递归函数还将具有一个或多个递归调用。在这里,我们只有一个。我们再次使用对象的属性subProperty
调用函数:return levelWithoutSubProperty (obj .subProperty)
对于此功能,我们可能还需要做一些其他事情,以使其更强大。在使用obj
之前,我们可能应该测试'subProperty' in obj
实际上是一个对象。而且我更喜欢使用表达式而不是像if
这样的语句。所以我可能会这样写:
const levelWithoutSubProperty = (obj) =>
typeof obj == 'object' && 'subProperty' in obj
? levelWithoutSubProperty (obj .subProperty)
: obj
我们可能希望通过将属性名称添加为参数来使其动态测试:
const deepest = (propName, obj) =>
typeof obj == 'object' && propName in obj
? deepest (propName, obj [propName])
: obj
并像deepest ('subProperty', obj)
这样称呼它。
但是,基本内容没有任何变化。我们有一个或多个直接返回值的基本案例,以及一个或多个递归调用,这些递归调用使用一些简化的数据再次调用我们的函数。
这就是递归的全部内容。
答案 2 :(得分:-1)
hasOwnProperty
可以检查对象是否具有指定为参数的属性。您可以创建一个while循环以继续,直到找到没有子属性的属性为止。这是一个简短的脚本,演示了执行此操作的功能。它将返回数组,在可能继续的所有时间中都为true,最后一次为false。
const obj = {
level1: 'level 1',
subProperty: {
level2: 'level 2',
subProperty: {
level3: 'level 3'
}
}
}
function getSubPropertyRecursive(obj, subProperty) {
propertyArray = [];
currentObj = obj
while (currentObj.hasOwnProperty(subProperty)){
currentObj = currentObj[subProperty];
propertyArray.push(true);
}
propertyArray.push(false);
return propertyArray;
}
console.log(getSubPropertyRecursive(obj, "subProperty"));