Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Javascript中编写递归函数,将深度嵌套对象的所有字符串值相加?_Javascript_Recursion - Fatal编程技术网

如何在Javascript中编写递归函数,将深度嵌套对象的所有字符串值相加?

如何在Javascript中编写递归函数,将深度嵌套对象的所有字符串值相加?,javascript,recursion,Javascript,Recursion,假设我有这个目标: { "prop1":"Hello", "prop2":{ "prop1":{ "prop1":"Tablecloth", "prop2":"Indians" }, "prop2":"JuicyJuice" }, "prop3":"Sponge", "prop4":{"Bob":"Squarepant

假设我有这个目标:

{
    "prop1":"Hello",
    "prop2":{
         "prop1":{
              "prop1":"Tablecloth",
              "prop2":"Indians"
                },
          "prop2":"JuicyJuice"
           },
    "prop3":"Sponge",
    "prop4":{"Bob":"Squarepants"}
}
我想要一个递归函数,它将返回
HelloTableClothIndiansJuice Juice SpongesQuarePants

无论我放置什么对象,我都希望它循环,直到它得到所有字符串并将它们相加


谢谢大家!

下面是一个非常简单的实现,它应该适用于以下简单对象:

var walkProps = function(obj) {
    var s = "";
    for(var x in obj)
    {
        if(typeof obj[x] === "string")
            s += obj[x];
        else
            s += walkProps(obj[x]);
    }
    return s;
}

但是请注意,这取决于
for in
访问对象属性的顺序,该顺序未指定,并且可能因引擎和对象的构造方式而异(例如,添加属性的顺序)


更新:稍加修改,即可根据键的字母顺序返回值。此方法对依赖于实现的属性排序不敏感:

var walkProps = function(obj) {
    var s = "", i = 0, keys = Object.keys(obj).sort(), i;
    for(; i < keys.length; i++)
    {
        if(typeof obj[keys[i]] === "string")
            s += obj[keys[i]];
        else
            s += walkProps(obj[keys[i]]);
    }
    return s;
}
var walkProps=函数(obj){
var s=“”,i=0,keys=Object.keys(obj).sort(),i;
对于(;i
因此,即使
“prop3”
出现在
“prop2”
之前,它仍将返回相同的输出


您需要编写一个函数,在对象的属性上循环,查看它们是否是字符串,然后将字符串附加到输出。如果属性是一个对象而不是一个字符串,则需要调用此对象上的函数,并将其返回值附加到总输出中

您可以在
中使用
for…循环对象的属性,如:

var MyObject = {
    'a': 'string1',
    'b': 'string2'
};

for (var key in MyObject) {
    var value = MyObject[key];
}
要检查属性是否为您想要执行的字符串,请执行以下操作:

typeof value === "string"
它将相应地返回true/false。

如前所述,
for(a中的var b)
可能不会保留顺序:

// Return array of string values
function getStrings(a) {
  if( typeof(a) == "string" ) return [a];
  var list = [];
  for( var b in a ) list = list.concat(getStrings(a[b]));
  return list;
}
适用于OP的数据:

var a = {
    "prop1":"Hello",
    "prop2":{
         "prop1":{
              "prop1":"Tablecloth",
              "prop2":"Indians"
                },
          "prop2":"JuicyJuice"
           },
    "prop3":"Sponge",
    "prop4":{"Bob":"Squarepants"}
}

getStrings(a).join(); // "Hello,Tablecloth,Indians,JuicyJuice,Sponge,Squarepants"

// Or as asked for by OP (again, order is not guaranteed)
getStrings(a).join(''); // "HelloTableclothIndiansJuicyJuiceSpongeSquarepants"

否,
中的
没有顺序,因为对象没有顺序。请参阅关于p.s.w.g答案的讨论。啊,我没有看到他需要一个特定的顺序,我不确定这是否可行,除非你们提到,字母顺序就可以了。从ECMAScript2015(ES6)开始,对象属性现在有一个顺序。除了在你们的示例中它确实保留了顺序之外?@RobertHarvey是的,我认为它是幸运的,而不是在所有情况下的保证。也许有些浏览器可以方便地保留排序。@马特对不起,你是对的,我太傻了,忽略了你答案的第一部分。但我不知道是谁否决了这个答案,因为这是一个可行的解决方案。这个答案依赖于未记录的、未指定的行为以及对象生成输出的构造方式(比如说,
SquarepantsTableclothIndiansJuicyJuiceSpongeHello
),基本上重复了p.s.w.g.@T.J.Crowder先前回答的前半部分。您是否阅读了此回答第一行的免责声明?这种行为是不可靠的。在我对OP问题的解释中,他可能只是举了个例子,而不是暗示必须对输出进行排序。如果你不同意,那么这不是我感兴趣的语义论点。如果OP认为这很有用,那就太好了;如果没有,那么让我们都有一个愉快的周末:)对象属性现在有一个顺序,从ECMAScript2015(ES6)开始,因此如果OP的对象定义如问题所示,这将确实可靠地产生所需的输出(在正确提供顺序的引擎上)。@T.J.Crowder很高兴知道。你有我可以参考的链接或章节号吗?对不起,我很惊讶我没有在上面链接。是的。它基本上是:其名称为字符串的属性,首先以升序数字顺序转换为整数;然后按属性添加到对象的顺序,将名称为尚未列出的字符串的属性;然后是名称为
Symbol
s的属性(按附加顺序)。这是他们自己的财产;原型属性显示在自己的属性之后,遵循相同的规则。