【问题标题】:How do I recursively find key name in nested objects that contain an empty object?如何在包含空对象的嵌套对象中递归查找键名?
【发布时间】:2016-10-24 07:57:48
【问题描述】:

我最初收到的回复是

var o={
    "StudentInfo": [{
        "Name1": [{
            "100": {
                "a": "12"
            }
        }, {
            "101": {
                "a": "50"
            }
        }]
    }, {
        "Name2": [{
            "102": {}
        }, {
            "103": {
                "b": "50"
            }
        }]
    }]
}

我有一个 JSON 对象,经过一些操作,对象为空(如空对象 102),我想打印它和父对象名称(如“Name2”)。

我试过了,

    var emptyKeys = [];
    var FLAG=false;

    function emptyObjToNull(object,keysArr){
        var isObject, hasKeys, isArray, current;
        for(var k in object){
            if(!object.hasOwnProperty(k))
                return;
            current = object[k];
            console.log("current KK "+k);
             console.log(current);

            isObject = typeof current == 'object';
            hasKeys = isObject && Object.keys(current).length !== 0;
            if(hasKeys){
                emptyObjToNull(current, keysArr);
            }else if(isObject && !hasKeys){
               //object[k] = null; // Set the key directly, not the reference
               FLAG=true;
               keysArr.push(k);
            }
        }
    }

emptyObjToNull(o,emptyKeys);

console.log(emptyKeys);

【问题讨论】:

  • 结构可以嵌套更多吗?
  • 你只想找空对象对吧?
  • 如果您的初始对象具有固定结构 - 无需使用递归,只需循环
  • 不,它不是固定的结构。是的,我想找到空对象及其父键。例如,如果 102 为空,我想打印“Name2”,如果 101 和 102 为空,那么我想分别打印“Name1”和“Name2”...
  • @user3265033:上面评论中的要求与问题的标题不一致。 102 不是空数组,是空对象。

标签: javascript json object


【解决方案1】:

如果我理解你的问题,应该这样做:

function doitNow(obj, emptyKeys) {
  var ittr = [];

  if (isObject(obj))
    ittr = Object.keys(obj);

  ittr.forEach(function(key) {
    if (isObject(obj[key]) && Object.keys(obj[key]).length === 0) {
      emptyKeys.push(key);
      obj[key] = null;

      // Array or object will return true. No need for explicit check
    } else if (isObject(obj[key]))
      obj[key] = doitNow(obj[key], emptyKeys);
  });

  return obj;
}

function isObject(o) {
  return typeof o == 'object';
}

本质上它会迭代一个对象属性或一个数组来寻找对象。如果一个对象没有属性,它将分配它为空。我认为这就是您想要从评论中得到的,但如果没有,可以将其删除。然后它将空对象键推送到传递的数组。最后返回对象。

一旦你有了键,你就不必对待数组和对象有任何不同了。数组只是具有数字整数属性的对象(以及与.length 的特殊关系)。我们只检查它是递归调用的数组还是对象。

Fiddle

【讨论】:

  • 您应该首先检查数组。 typeof a 也将返回 object
  • @Rajesh 实际上这使它更容易,不需要检查。数组上的Object.keys 将返回数字属性。有趣的从来没有这样做过。不知道我觉得你该不该。编辑:查看MDN 似乎完全可以接受。
  • 那么您应该删除对Array.isArray 的检查。在循环之前还要检查ittr 是否为数组类型。如果 ittr 类似于 "a": "50",这将失败,因为它没有 forEach 函数
  • @Rajesh 修改了,还是找到了更好的方法。
【解决方案2】:

你可以试试递归。

注意:这不会得到很好的优化,并且对于具有高嵌套的大型 JSON 可能会引发错误(超出最大堆栈大小)。

JSFiddle

var o={StudentInfo:[{Name1:[{100:{a:"12"},1000:{}},{101:{a:"50"}}]},{Name2:[{102:{}},{103:{b:"50"}}]}]};

function findEmptyObjects(obj, parent) {
  var result = [];
  Object.keys(obj).forEach(function(key) {
    var _o = obj[key];
    if (Array.isArray(_o)) {
      _o.forEach(function(_item) {
        if (typeof(_item) === "object")
          result = result.concat(findEmptyObjects(_item, key))
      })
    } else if (typeof(_o) === "object") {
      if (isEmptyObject(_o)) {
        result.push({
          "object": key,
          "parent": (parent || "")
        })
      } else
        result = result.concat(findEmptyObjects(_o, key));
    }
  });
  return result;
}

function isEmptyObject(obj) {
  return typeof(obj) === "object" && Object.keys(obj).length === 0;
}

var r = findEmptyObjects(o, undefined);
console.log(r)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 2018-02-14
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    相关资源
    最近更新 更多