简体   繁体   中英

Remove JSON object with same id recursively

I have a JSON list with duplicates I need to remove, but I can't find a way to do it.

This is the solution that I have.

I want to keep the first item found with a given ID, and remove the next ones with the same ID.

The problem is, it tries to remove even the first item.

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));

finally, this is the original 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,
      }
    ]
  }
]

and this is the result I would like to obtain

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

thank you for your reply.

I tried creating my own logic for this (probably more general than what you want), but it may help you debug your code. See the jsFiddle .

The core of the logic is

/**
 * 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];
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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