jQuery递归迭代对象

30
前几天我想在jQuery中使用一个对象迭代器,该迭代器有一个标志,可以设置为递归迭代子对象。我认为它是jQuery.each()的一部分,但现在在文档中找不到该功能。
是否存在这样的迭代器,可以自动递归?(我知道如何在javascript中实现。只是想知道我是否真的看到了我认为看到的东西。)
非常感谢!
编辑:为了明确起见,我正在考虑像jQuery.each()这样的实用方法,它将递归迭代javascript对象及其嵌套对象。
给定下面的示例,each()方法将遍历所有对象,包括myobj.obj2.key2中的嵌套对象。
我敢肯定我在jQuery文档中看到过关于此的内容,但现在找不到了。
谢谢。
var myobj = {
    obj1: {key1:'val1', key2:'val2'},
    obj2: {key1:'val1', key2: {nest1:'val1', nest2:'val2', nest3:'val3'}},
    obj3: {key1:'val1', key2:'val2'}
}

$jQuery.each(myobj, function(key,val) {
    // Code to run over each key/val pair
    // Does so recursively to include all nested objects
})

你期望这个看起来是什么样子?哪些键值对被展示了? - tooleb
我想我只是认为它会进行'typeof'测试或类似的操作,并在找到对象时跳转到该对象。键/值对将用于当前所在的任何对象。 - user113716
4个回答

39

.find('selector')方法基本上是.children()方法的递归版本,它会查找与选择器匹配的任何后代对象,而.children()只能查找第一级后代中的对象。

第二次修改(我之前表述不好,代码有点乱!):

好吧,我认为这个功能作为一个标志并没有意义:你可以很愉快地对该对象进行无限递归(相信我,我曾经用它破坏了Firefox),因此你需要某种交互来确保只有在子对象是有效的递归候选时才进行递归。

你需要做的就是将函数分成如下的形式:

var myobj = {
  obj1: {
    key1: 'val1',
    key2: 'val2'
  },
  obj2: {
    key1: 'val1',
    key2: {
      nest1: 'val1',
      nest2: 'val2',
      nest3: 'val3'
    }
  },
  obj3: {
    key1: 'val1',
    key2: 'val2'
  }
}

$jQuery.each(myobj, function(key, val) {
  recursiveFunction(key, val)
});

function recursiveFunction(key, val) {
  actualFunction(key, val);
  var value = val['key2'];
  if (value instanceof Object) {
    $.each(value, function(key, val) {
      recursiveFunction(key, val)
    });
  }

}

function actualFunction(key, val) {
  /// do stuff
}

抱歉,Ed,我表达不清楚。我的意思是像jQuery.each()这样的实用程序,可以递归地迭代javascript对象,而不是DOM。 - user113716
嗨,Ed。你能解释一下关于不同类型的问题吗?对我来说,似乎它会依赖于不同的类型来检测对象的存在。另外,我对你回答中的if()语句部分有点困惑,可能是因为我完全没有考虑到DOM。而只是一个用于后台处理的Javascript实用程序(当然,在需要时它可以与DOM交互)。谢谢。 - user113716
我说过命名是个糟糕的例子!如果一些匿名对象被传递到你的each()函数中,那么它可能会导致未定义的行为。如果key2恰好是一个整数数组,并且你尝试对它们进行字符串比较,会发生什么?像我们之前说的那样,实现一个递归覆盖each()的catch-all函数几乎是微不足道的,所以它没有被实现的事实表明,在那种形式下它不太可能有用,或者会带来更多的麻烦! - Ed James
好的,我明白你的意思。我想如果一个人设置了标志,那么他们也应该知道并控制对象中存储的数据。jQuery 中的任何东西都可能被误用。关键是在适当的情况下使用它,可以节省一些编码工作。不过,你已经回答了我的问题。jQuery 中没有这样的功能。感谢你的建议。 - user113716
尝试这段代码,但一开始就似乎需要知道哪些键名是对象,而不是简单的值:var value = val['key2']; - TARKUS
显示剩余5条评论

9
@Ed Woodcock上面的稍微简化版本。我需要使用它来输出一个具有命名链接的HTML项目列表。
var list = "<ul>";
$.each(data, recurse);

function recurse(key, val) {
    list += "<li>";
    if (val instanceof Object) {
        list += key + "<ul>";
        $.each(val, recurse);
        list += "</ul>";
    } else {
        list += "<a href='" + val + "'>" + key + "</a>";
    }
    list += "</li>";
}
list += "</ul>";

$("#container").html(list);

1

你可以这样更轻松地完成

$(this).children().each(function(index, element) {
...
});

0

这个问答非常有帮助。谢谢你。(我也很感激饼干的参考。我还在苦苦挣扎着那本书!)

这是我的版本,使用“搜索和替换”来实现一个简单的i18n jQuery解决方案(这可能对某些人有帮助)。它查找包含在类中的术语,并在字典中找到该术语时进行替换。

Fiddle: http://jsfiddle.net/orolo/CeY5Y/11/

HTML:

In the <span class="i18n">Clear</span> and also <span class="i18n">Save Widget</span>. I'm <span class="i18n">On</span> the <span class="i18n">sub3</span> and <span class="i18n">PDF</span>.

JavaScript / jQuery:

var term = "";

var customDict = {
    "Level One": {
        "Clear": "1234",
        "CSV": "CSV",
        "First": "First",
        "Last": "Last",
        "Next": "Next",
        "On": "42",
        "Off": "Off",
        "PDF": "alpha",
        "Prev": "Prev",
        "Rows": "Rows",
        "Save Widget": "saver widgetor",
        "Stats": "statistiques",
        "sub": {
            "sub2": {
                "sub3": "inception"
            }
        }
    }
};

function recursiveLookup(key, val) {
    //test for a match between term and key
    if (key === term) {
        $('.i18n').each(function() {
            if ($(this).text() === key) {
              $(this).text(val);  
            }
        });
    }
    //val is an object or no match? recur
    if (val instanceof Object) {
        $.each(val, function(key1, val1) {
            recursiveLookup(key1, val1);
        });
    }
}

function convert() {    
    $('.i18n').each(function(key, val) {
        term = $(this).text();  
        $.each(customDict, function(key, val) {
            recursiveLookup(key, val);
        });

    });
}


/*call the function*/
convert();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接