以递归方式删除具有相同id的JSON对象

时间:2014-07-09 14:45:55

标签: javascript jquery json recursion

我有一个需要删除的重复项的JSON列表,但我找不到办法。

这是我的解决方案。

我想保留使用给定ID找到的第一个项目,然后删除具有相同ID的下一个项目。

问题是,它试图删除第一个项目。

var gindex = [];

function removeDuplicate(list) {

    $.each(list, function(i, val){
        console.log(val.id);
        console.log(gindex);
        if($.inArray(val.id, gindex) == -1) { //in array, so leave this item
            gindex.push(val.id);
        }
        else // found already one with the id, delete it
        {
            list.splice(i, 1);
        }

        if(val.children) {
            val.children = removeDuplicate(val.children);
        }

    });

    return list;
}

gindex = [];
list = removeDuplicate(parsed_list);
console.log(window.JSON.stringify(list));

最后,这是原始列​​表:

[
  {
    "id": 0,
    "children": [
      {
        "id": 1,
        "children": [
          {
            "id": 2, // with my algorithm, this one get also flagged for deletion
          }
        ]
      },
      {
        "id": 2, // remove this one
      },
      {
        "id": 3,
      },
      {
        "id": 4, // with my algorithm, this one get also flagged for deletion
        "children": [
          { 
            "id": 5, // with my algorithm, this one get also flagged for deletion
            "children": [
              {
                "id": 6, // with my algorithm, this one get also flagged for deletion
              }
            ]
          }
        ]
      },
      {
        "id": 5, // remove this one
        "children": [
          {
            "id": 6, // remove this one
          }
        ]
      },
      {
        "id": 6, // remove this one
      },
      {
        "id": 7,
      }
    ]
  }
]

这是我想获得的结果

[
  {
    "id": 0,
    "children": [
      {
        "id": 1,
        "children": [
          {
            "id": 2,
          }
        ]
      },
      {
        "id": 3,
      },
      {
        "id": 4,
        "children": [
          {
            "id": 5,
            "children": [
              {
                "id": 6,
              }
            ]
          }
        ]
      },
      {
        "id": 7,
      }
    ]
  }
]

谢谢你的回复。

1 个答案:

答案 0 :(得分:0)

我尝试为此创建自己的逻辑(可能比您想要的更通用),但它可以帮助您调试代码。请参阅jsFiddle

逻辑的核心是

/**
 * Walk through an object or array and remove duplicate elements where the 'id' key is duplicated
 * Depends on a seenIds object (using it as a set)
 */
function processData(el) {
    // If the element is an array...
    if ($.isArray(el)) {
        for (var i = 0; i < el.length; i++) {
            var value = el[i];
            processData(value);

            // If the child is now empty, remove it from the array
            if (checkForEmpty(value)) {
                el.splice(i, 1);
                i--; // Fix index after splicing (http://stackoverflow.com/a/9882349/1370556)
            }
        }
    }
    // If the element is an object...
    else if ($.isPlainObject(el)) {
        for (var key in el) {
            // Make sure the key is not part of the prototype chain
            if (el.hasOwnProperty(key)) {
                var value = el[key];

                if (key == 'id') {
                    // If the key has been seen, remove it
                    if (seenIds[value]) {
                        delete el[key];
                        continue; // Skip further processing
                    } else seenIds[value] = true;
                }

                processData(value);

                // If the child is now empty, remove it from the object
                if (checkForEmpty(value)) delete el[key];
            }
        }
    }
}