下面是问题:
//获取最长名称
///编写一个带有对象的函数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:未定义DescendentLongestName
我做错了什么?
答案 0 :(得分:1)
您可以使用两部分,一部分用于检查键,而递归部分用于获取嵌套对象的键。
function getLongestKey(object, keys = []) {
return Object.keys(object).reduce((r, k) => {
if (!r || r[0].length < k.length) {
r = [k];
} else if (r[0].length === k.length) {
r.push(k);
}
return object[k] && typeof object[k] === 'object'
? getLongestKey(object[k], r)
: r;
}, undefined)
}
let family = { 'Beverly Marquez': { 'Nina Rhone': { 'William Rhodes': null, 'Paul Nell': null, 'Sir Paddington the Fourth, of the county Wilstonshire': null } } };
console.log(getLongestKey(family));
答案 1 :(得分:1)
我不知道如何解决您的代码,但我想提出一个新的解决方案。
想法是将您的问题分解为两个部分:
let longest = ary => ary
.reduce((max, x) =>
x.length > max.length ? x : max, '');
let allKeys = obj => obj
? Object.keys(obj).concat(
...Object.values(obj).map(allKeys))
: [];
//
let family = {
'Beverly Marquez': {
'Nina Rhone': {
'William Rhodes': null,
'Paul Nell': null,
'Sir Paddington the Fourth, of the county Wilstonshire': null,
}
}
};
console.log(longest(allKeys(family)));
答案 2 :(得分:0)
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;
}
答案 3 :(得分:0)
由于键及其值可以争夺具有最长字符串的字符串,因此在递归函数中使用Object.entries
可能很有意义:
var family = {
'Beverly Marquez': {
'Nina Rhone': {
'William Rhodes': null,
'Paul Nell': null,
'Sir Paddington the Fourth, of the county Wilstonshire': null,
}
}
};
const longest = (obj, cur = '') =>
Object.entries(obj).reduce((max, [key, val]) => {
const candidate = (val && longest(val, max)) || key;
return candidate.length > max.length ? candidate : max; }, cur);
console.log(longest(family));
答案 4 :(得分:0)
使用for...in
循环遍历family
对象中的键值对。如果值是一个对象,请使用递归遍历该对象,以查看该对象的键是否长于它之前的任何键。返回最长的键(名称)。
function getLongestName(family) {
let longest = "";
for (let key in family) {
//create initial longest
if (key.length > longest.length) {
longest = key;
}
let value = family[key];
//if value is an object
if (typeof value === "object") {
//use recursion to get the key-values of that value
let descendant = getLongestName(value);
//if descendant's name is longer than longest, assign it to 'longest'
if (descendant.length > longest.length) {
longest = descendant;
}
}
}
return longest;
}
console.log(getLongestName(family));
答案 5 :(得分:0)
我将从一个简单的函数traverse
-
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 family = {
'Beverly Marquez': {
'Nina Rhone': {
'William Rhodes': null,
'Paul Nell': null,
'Sir Paddington the Fourth, of the county Wilstonshire': null
}
}
}
const traverse = function* (t = {})
{ if (t == null) return
for (const [ name, children ] of Object.entries(t))
{ yield name
yield* traverse(children)
}
}
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
console.log(Array.from(traverse(family)))
// [ "Beverly Marquez"
// , "Nina Rhone"
// , "William Rhodes"
// , "Paul Nell"
// , "Sir Paddington the Fourth, of the county Wilstonshire"
// ]
如果树中还有其他数据,则可以看到使用traverse
编写其他函数也很容易-
const myTree =
{ name: "Alice"
, gender: "F"
, children:
[ { name: "Bob"
, gender: "M"
, children:
[ { name: "Charles"
, gender: "M"
}
]
}
]
}
const traverse = function* ({ children = [], ...t })
{ yield t
for (const child of children)
yield* traverse(child)
}
const filter = function* (test, t = {})
{ for (const leaf of traverse(t))
if (test(leaf))
yield leaf
}
const byGender = (q = "", t = {}) =>
filter(node => node.gender === q, t)
console.log(Array.from(byGender("M", myTree)))
// [ { name: "Bob", gender: "M" }, { name: "Charles", gender: "M" } ]
console.log(Array.from(byGender("F", myTree)))
// [ { name: "Alice", gender: "F" } ]