Javascript:递归问题-->;返回深度嵌套对象中最长的键值
问题如下: //获得最长名称 //编写一个函数getLongestName,它接受一个对象。该对象表示一个族树。返回族中最长的名称 这是代码,但返回了一个错误: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
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].长度
- 递归查找嵌套对象中的所有键
- 从字符串数组中查找最长的字符串
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:是的,我用更好的实现替换了最长的
。