通过键深嵌套对象查找通过键深嵌套对象查找(Find by key deep in a nested

2019-05-06 12:07发布

比方说,我有一个对象:

[
    {
        'title': "some title"
        'channel_id':'123we'
        'options': [
                    {
                'channel_id':'abc'
                'image':'http://asdasd.com/all-inclusive-block-img.jpg'
                'title':'All-Inclusive'
                'options':[
                    {
                        'channel_id':'dsa2'
                        'title':'Some Recommends'
                        'options':[
                            {
                                'image':'http://www.asdasd.com'                                 'title':'Sandals'
                                'id':'1'
                                'content':{
                                     ...

我想找到一个对象,其中ID为1。是否有这样的功能? 我可以用下划线的_.filter方法,但我将不得不开始在顶部和下渗。

Answer 1:

递归是你的朋友。 我更新的功能,占财产数组:

function getObject(theObject) {
    var result = null;
    if(theObject instanceof Array) {
        for(var i = 0; i < theObject.length; i++) {
            result = getObject(theObject[i]);
            if (result) {
                break;
            }   
        }
    }
    else
    {
        for(var prop in theObject) {
            console.log(prop + ': ' + theObject[prop]);
            if(prop == 'id') {
                if(theObject[prop] == 1) {
                    return theObject;
                }
            }
            if(theObject[prop] instanceof Object || theObject[prop] instanceof Array) {
                result = getObject(theObject[prop]);
                if (result) {
                    break;
                }
            } 
        }
    }
    return result;
}

更新的jsfiddle: http://jsfiddle.net/FM3qu/7/



Answer 2:

如果你想获得的第一个元素的ID是当对象被搜索1,您可以使用此功能:

function customFilter(object){
    if(object.hasOwnProperty('id') && object["id"] == 1)
        return object;

    for(var i=0; i<Object.keys(object).length; i++){
        if(typeof object[Object.keys(object)[i]] == "object"){
            var o = customFilter(object[Object.keys(object)[i]]);
            if(o != null)
                return o;
        }
    }

    return null;
}

如果你想获得id为1,则(ID为1存储在结果正如你看到的所有元素)的所有元素:

function customFilter(object, result){
    if(object.hasOwnProperty('id') && object.id == 1)
        result.push(object);

    for(var i=0; i<Object.keys(object).length; i++){
        if(typeof object[Object.keys(object)[i]] == "object"){
            customFilter(object[Object.keys(object)[i]], result);
        }
    }
}


Answer 3:

什么工作对我来说是这样的偷懒的办法,而不是算法懒惰;)

if( JSON.stringify(object_name).indexOf("key_name") > -1 ) {
    console.log("Key Found");
}
else{
    console.log("Key not Found");
}


Answer 4:

我通过google搜索了类似的功能找到了这个网页。 基于扎克和regularmike提供的工作,我创建了适合我的需要另一个版本。
BTW,teriffic工作ZAH和regularmike! 我会在这里发布的代码:

function findObjects(obj, targetProp, targetValue, finalResults) {

  function getObject(theObject) {
    let result = null;
    if (theObject instanceof Array) {
      for (let i = 0; i < theObject.length; i++) {
        getObject(theObject[i]);
      }
    }
    else {
      for (let prop in theObject) {
        if(theObject.hasOwnProperty(prop)){
          console.log(prop + ': ' + theObject[prop]);
          if (prop === targetProp) {
            console.log('--found id');
            if (theObject[prop] === targetValue) {
              console.log('----found porop', prop, ', ', theObject[prop]);
              finalResults.push(theObject);
            }
          }
          if (theObject[prop] instanceof Object || theObject[prop] instanceof Array){
            getObject(theObject[prop]);
          }
        }
      }
    }
  }

  getObject(obj);

}

它所做的是它发现任何物体内部obj与属性名称和值匹配targetProptargetValue ,并将它推到finalResults阵列。 和这里的发挥各地的jsfiddle: https://jsfiddle.net/alexQch/5u6q2ybc/



Answer 5:

我创建库用于这一目的: https://github.com/dominik791/obj-traverse

您可以使用findFirst()这样的方法:

var foundObject = findFirst(rootObject, 'options', { 'id': '1' });

而现在foundObject变量存储到你要找的对象的引用。



Answer 6:

改进@haitaka答案,使用该密钥和谓语

function  deepSearch (object, key, predicate) {
    if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) return object

    for (let i = 0; i < Object.keys(object).length; i++) {
      if (typeof object[Object.keys(object)[i]] === "object") {
        let o = deepSearch(object[Object.keys(object)[i]], key, predicate)
        if (o != null) return o
      }
    }
    return null
}

因此,这可以被调用为:

var result = deepSearch(myObject, 'id', (k, v) => v === 1);

要么

var result = deepSearch(myObject, 'title', (k, v) => v === 'Some Recommends');

这里是的jsfiddle: http://jsfiddle.net/ktdx9es7



Answer 7:

改进的答案要考虑到对象中考虑循环引用。 它也显示了它到那里的路径。

在这个例子中,我寻找,我知道是一个全局对象内的某处的iframe:

const objDone = []
var i = 2
function getObject(theObject, k) {
    if (i < 1 || objDone.indexOf(theObject) > -1) return
    objDone.push(theObject)
    var result = null;
    if(theObject instanceof Array) {
        for(var i = 0; i < theObject.length; i++) {
            result = getObject(theObject[i], i);
            if (result) {
                break;
            }   
        }
    }
    else
    {
        for(var prop in theObject) {
            if(prop == 'iframe' && theObject[prop]) {
                i--;
                console.log('iframe', theObject[prop])
                return theObject[prop]
            }
            if(theObject[prop] instanceof Object || theObject[prop] instanceof Array) {
                result = getObject(theObject[prop], prop);
                if (result) {
                    break;
                }
            } 
        }
    }
    if (result) console.info(k)
    return result;
}

运行以下: getObject(reader, 'reader')得到如下的输出,并在结束的IFRAME元素:

iframe // (The Dom Element)
_views
views
manager
rendition
book
reader

注:路径是相反的顺序reader.book.rendition.manager.views._views.iframe



Answer 8:

如果您已经使用下划线,请使用_.find()

_.find(yourList, function (item) {
    return item.id === 1;
});


文章来源: Find by key deep in a nested object