使用id

时间:2019-02-14 11:59:05

标签: javascript json recursion

如果ID与ID匹配,我想删除整个JSON对象,从而使JSON的结构保持一致。我的示例json看起来像这样:

{
	"menu": {
		"id": "1",
		"value": "File",
		"popup": {
			"children": [{
					"value": "New",
					"onclick": "Some click value",
					"id": "2"
				},
				{
					"value": "Open",
					"onclick": "OpenDoc()",
					"id": "3"
				},
				{
					"value": "Close",
					"onclick": "CloseDoc()",
					"id": "4"
				}
			]
		}
	}
}

如果ID匹配,我想删除整个对象。我的代码看起来像这样

static deleteJsonObject(myJson, objectId) {
    for(var key in myJson) {
      if (_.isArray(myJson[key])) {
        if(myJson[key].length == 0) {
          return
        }
        if(objectId == myJson['id']) {
          delete myJson[key]
        }
        
        this.deleteJsonObject(myJson[key], objectId);
      } else if (_.isObject(myJson[key])) {
        if(objectId == myJson['id']) {
          delete myJson[key]
        }
        this.deleteJsonObject(myJson[key], objectId);
      } 
      else if (_.isString(myJson[key])) {
        if(objectId == myJson['id']) {
          delete myJson[key]
        }
      }
    }
    return myJson
  }

我的代码的问题是,如果它是子元素,它只会删除id而不是整个对象。任何帮助表示赞赏。请注意,删除后我不想有空对象。它应该从json完全删除对象。没有空对象或空对象。

2 个答案:

答案 0 :(得分:0)

完成目标的一种安全方法是在树中执行Depth-first search,如果ID匹配,则删除整个对象。

const data = {
    "menu": {
        "id": "1",
        "value": "File",
        "popup": {
            "children": [{
                    "value": "New",
                    "onclick": "Some click value",
                    "id": "2"
                },
                {
                    "value": "Open",
                    "onclick": "OpenDoc()",
                    "id": "3"
                },
                {
                    "value": "Close",
                    "onclick": "CloseDoc()",
                    "id": "4"
                }
            ]
        }
    }
}

const deleteByID = (tree, id) =>
{
    // First we iterate every element of the object
    for (const key in tree)
    {
        const node = tree[key]

        // If the element id matches we delete the whole element
        if (node.id == id)
        {
            // If the parent of this element is a Array, we must remove it with splice
            if (tree instanceof Array)
            {
                tree.splice(key, 1)
            }
            // Else, we can use the delete operator to delete the property
            else
            {
                delete tree[key]
            }
        }
        // If the element id don't match (or the element doesn't have a id property), we recursively iterate all it's properties
        else if (typeof node === 'object')
        {
            deleteByID(node, id)
        }
    }
}

deleteByID(data, 3)

console.log(data)

答案 1 :(得分:0)

尝试一下:

var obj = {
	"menu": {
		"id": "1",
		"value": "File",
		"popup": {
			"children": [{
					"value": "New",
					"onclick": "Some click value",
					"id": "2"
				},
				{
					"value": "Open",
					"onclick": "OpenDoc()",
					"id": "3"
				},
				{
					"value": "Close",
					"onclick": "CloseDoc()",
					"id": "4"
				}
			]
		}
	}
};

var id = "2";

function deleteObject(obj, id) {
	if (obj.menu.id === id) {
  	delete obj.menu;
  } else if (Object.keys(obj.menu).includes('popup')) {
  	var result = obj.menu.popup.children.filter(item => {
    	if (item.id === id) {
      	obj.menu.popup.children.splice(obj.menu.popup.children.indexOf(item), 1);
      }
    });
  }
  return obj;
}

var res = deleteObject(obj, id);

console.log(res);