Javascript:递归问题-->;返回深度嵌套对象中最长的键值

Javascript:递归问题-->;返回深度嵌套对象中最长的键值,javascript,object,recursion,nested,key,Javascript,Object,Recursion,Nested,Key,问题如下: //获得最长名称 //编写一个函数getLongestName,它接受一个对象。该对象表示一个族树。返回族中最长的名称 这是代码,但返回了一个错误: let family = { 'Beverly Marquez': { 'Nina Rhone': { 'William Rhodes': null, 'Paul Nell': null, 'Sir Paddington the Fourth, of the county Wilstons

问题如下:

//获得最长名称

//编写一个函数getLongestName,它接受一个对象。该对象表示一个族树。返回族中最长的名称

这是代码,但返回了一个错误:

let family = {
  'Beverly Marquez': {
    'Nina Rhone': {
      'William Rhodes': null,
      'Paul Nell': null,
      'Sir Paddington the Fourth, of the county Wilstonshire': null
    }
  }
};


function getLongestName (family){

  let longestName = ''; 

  for (let key in family){
    let value = family[key]
    console.log(value)

    if (typeof value === 'object'){
      let descendentLongestName = getLongestName (value)
    }

    else {
      descendentLongestName = value
    }

    if (descendentLongestName.length > longestName.length){
      let longestName = descendentLongestName
    }
  }
  return longestName; 
}


getLongestName(family); // => 'Sir Paddington the Fourth, of the county Wilstonshire'
当我运行上面的代码时,我得到以下错误:ReferenceError:downentlongestname未定义


我做错了什么

let作用域是特定于块的,因此 如果您想使用它,那么在块之外声明它,否则使用var

function getLongestName (family){

  let longestName = ''; 

  for (let key in family){
    let value = family[key]
    console.log(value)
let descendentLongestName='';
    if (typeof value === 'object'){
      descendentLongestName = getLongestName (value)
    }

    else {
      descendentLongestName = value
    }
let longestName;
    if (descendentLongestName && descendentLongestName.length > longestName.length){
     longestName = descendentLongestName
    }
  }
  return longestName; 
}



您可以使用两个部分,一个用于检查键,另一个用于获取嵌套对象键的递归部分

函数getLongestKey(对象,键=[]){ 返回Object.keys(Object.reduce)(r,k)=>{ if(!r | | r[0].长度console.log(getLongestKey(family))我不知道如何修复您的代码,但我想建议一种新的解决方案

我们的想法是将您的问题分解为两部分:

  • 递归查找嵌套对象中的所有键
  • 从字符串数组中查找最长的字符串
let longest=ari=>ari
.减少((最大值,x)=>
x、 长度>最大长度?x:max',);
让allKeys=obj=>obj
? Object.keys(obj.concat)(
…Object.values(obj.map)(所有键))
: [];
//
让家庭={
贝弗利·马奎兹:{
“尼娜·罗纳”:{
“William Rhodes”:空,
“Paul Nell”:空,
“威尔斯顿郡第四位帕丁顿爵士”:空,
}
}
};

console.log(最长(所有键(系列))由于键及其值可以竞争最长的字符串,因此在递归函数中使用可能有意义:

var系列={
贝弗利·马奎兹:{
“尼娜·罗纳”:{
“William Rhodes”:空,
“Paul Nell”:空,
“威尔斯顿郡第四位帕丁顿爵士”:空,
}
}
};
常量最长=(对象,当前=“”)=>
Object.entries(obj).reduce((最大值,[key,val])=>{
常量候选=(val&&最长(val,max))|键;
返回candidate.length>max.length?candidate:max;},cur);

控制台日志(最长(系列))使用
for…in
循环遍历
系列
对象中的键值对。如果该值是一个对象,则使用递归循环该对象,以查看该对象的键是否比它之前的任何键都长。返回最长的键(名称)

函数getLongestName(系列){ 让最长的=”; 用于(让输入家庭){ //创建初始最长 如果(key.length>longest.length){ 最长=键; } 让值=族[键]; //如果值是一个对象 如果(值的类型==“对象”){ //使用递归获取该值的键值 让后代=getLongestName(值); //如果子代名称的长度超过最长,请将其指定为“最长” if(后代.length>最长.length){ 最长=后代; } } } 返回时间最长; }
console.log(getLongestName(family))我将从一个简单的函数开始
遍历
-

const traverse = function* (t = {})
{ if (t == null) return
  for (const [ name, children ] of Object.entries(t))
  { yield name
    yield* traverse(children)
  }
}

console.log(Array.from(traverse(family)))
// [ "Beverly Marquez"
// , "Nina Rhone"
// , "William Rhodes"
// , "Paul Nell"
// , "Sir Paddington the Fourth, of the county Wilstonshire"
// ]
这将树的遍历与希望对树的值执行的操作分离。现在我们实现了一个简单的
longestName
函数-

const longestName = (t = {}) =>
{ let r = ""
  for (const name of traverse(t))
    if (name.length > r.length)
      r = name
  return r
}

console.log(longestName(family))
// Sir Paddington the Fourth, of the county Wilstonshire
正如您所看到的,现在编写
longestName
很容易,因为我们不必同时关注遍历逻辑

展开下面的代码段,在您自己的浏览器中验证结果-

let族={
贝弗利·马奎兹:{
“尼娜·罗纳”:{
“William Rhodes”:空,
“Paul Nell”:空,
“威尔斯顿郡第四位帕丁顿爵士”:空
}
}
}
常量遍历=函数*(t={})
{if(t==null)返回
for(Object.entries(t))的常量[名称,子项]
{产生名称
收益率*遍历(子项)
}
}
const longestName=(t={})=>
{let r=“”
for(导线的常数名称(t))
如果(name.length>r.length)
r=名称
返回r
}
console.log(最长名称(系列))
//帕丁顿爵士,威尔斯顿郡的第四个
console.log(数组.from(遍历(族)))
//[“贝弗利·马奎兹”
//“尼娜·罗纳”
//“威廉·罗德斯”
//“保罗·内尔”
//“威尔斯顿郡第四位帕丁顿爵士”

//]
您需要在声明
longestName
的地方声明
longestName
而不是在
if
块中。如果
已经声明了
longestName
,则不需要
放在最后一个
中。当我运行上面的代码时,getLongestName(family)返回“
sort()
修改数组。最好先复制一下。e、 g.
[…ary].sort(/*…*/)
@customcommander:是的,我用更好的实现替换了
最长的