简体   繁体   English

递归扩展Jquery对象

[英]Extend a Jquery object recursively

I'm trying to extend a javascript object in a repeatable fashion without having to iterate through my element too much. 我试图以可重复的方式扩展javascript对象,而不必过多地遍历我的元素。 This is a very simple example to illustrate the question: 这是一个非常简单的示例来说明问题:

var test1 = [
            {
              tests: [
                {
                  label: "this is a test"
                },
                {
                  label: "this is a test"
                },
                {
                  label: "this is a test"
                }
              ]}];

var test2 = [
            {
              tests: [
                  {comments: 'this is a comment'}
              ]}];

console.log($.extend(true, test1, test2))

http://jsfiddle.net/76bBR/3/ http://jsfiddle.net/76bBR/3/

The way it works now the comment item will only apply to the first element in test1. 现在,注释项仅适用于test1中的第一个元素。 I am wondering if there is a nifty way to do this such that it applies to all without having to do forEach. 我想知道是否有一种巧妙的方法可以使它适用于所有人而不必做forEach。 Obviously in this small case forEach will be fine, but in my real example I have a very deep object with several lists which I want to merge with static data for each of the items. 显然,在这种小情况下,forEach会很好,但是在我的实际示例中,我有一个非常深的对象,其中包含几个列表,我想与每个项目的静态数据合并。 Are there any cool tools out there which make this easy? 有没有很酷的工具可以简化这一过程?

var idealResult = [
            {
              tests: [
                {
                  label: "this is a test",
                  comments: 'this is a comment'
                },
                {
                  label: "this is a test",
                  comments: 'this is a comment'
                },
                {
                  label: "this is a test",
                  comments: 'this is a comment'
                }
              ]}];

I tried playing around with a recursive algorithm, see this jsFiddle . 我尝试使用递归算法,请参阅jsFiddle

function recursiveAppend(src, dest) {
    // If it's an array, loop through elements
    if ($.isArray(src)) {
        for (var i = 0; i < src.length; i++) {
            // If function returns true, then it found the 'deepest' level...
            if ( recursiveAppend(src[i], dest[i]) ) {
                // ...so extend all objects in the destination...
                for (var j = 0; j < dest.length; j++) {
                    $.extend(true, dest[j], src[i]);
                }
                // ...and stop looping
                break;
            }
        }
    }
    // If it's an object, loop through keys
    else if ($.isPlainObject(src)) {
        for (var key in src) {
            if (src.hasOwnProperty(key)) {
                // Check if the destination has the key
                if (dest.hasOwnProperty(key)) {
                    return recursiveAppend(src[key], dest[key])
                }
                // If it doesn't, then we found the 'deepest' level
                else {
                    //debugger;
                    return true;
                }
            }
        }
    }
    else {
        //debugger;
        return true;
    }
};

This algorithm makes the assumption that your src and dest have the same structure (regardless of what it is) until the deepest level, where dest will then consist of an array of objects analogous to src 's single object. 该算法假设您的srcdest具有相同的结构(无论它是什么),直到最深层次为止,然后dest将由类似于src的单个对象的对象数组组成。

It also stops after it finds the first non-array/non-object key. 找到第一个非数组/非对象键之后,它也会停止。

It's not fully tested, so throw a lot of random test cases at it! 它没有经过完全测试,因此请扔很多随机测试用例! You'll want to add protections against src and dest being different structures (I always assume there will be corresponding pairs of src[i] , dest[i] or src[key] , dest[key] ). 您需要添加针对srcdest保护,使其结构不同(我一直假设将有相应的src[i]dest[i]src[key]dest[key] )。

Hopefully this points you in the right direction =) 希望这会为您指明正确的方向=)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM