在嵌套数组中的深层按键查找

vxbzzdmp  于 2022-09-21  发布在  Node.js
关注(0)|答案(22)|浏览(271)

假设我有一个物体:

[
    {
        '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方法,但我必须从顶部开始并向下过滤。

hgb9j2n6

hgb9j2n616#

另一种递归解决方案,适用于数组/列表和对象,或两者的混合:

function deepSearchByKey(object, originalKey, matches = []) {

    if(object != null) {
        if(Array.isArray(object)) {
            for(let arrayItem of object) {
                deepSearchByKey(arrayItem, originalKey, matches);
            }
        } else if(typeof object == 'object') {

            for(let key of Object.keys(object)) {
                if(key == originalKey) {
                    matches.push(object);
                } else {
                    deepSearchByKey(object[key], originalKey, matches);
                }

            }

        }
    }

    return matches;
}

用法:

let result = deepSearchByKey(arrayOrObject, 'key'); // returns an array with the objects containing the key
hsvhsicv

hsvhsicv17#

为此,我创建了库:https://github.com/dominik791/obj-traverse

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

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

现在foundObject变量存储了对您正在查找的对象的引用。

px9o7tmv

px9o7tmv18#

我通过谷歌搜索找到了这个页面,寻找类似的功能。基于Zach和Regarmike提供的工作,我创建了另一个适合我需求的版本。
顺便说一句,交通工作和规则!我将在此处发布代码:

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/

f2uvfpb9

f2uvfpb919#

改进了@haitaka答案,使用了键和 predicate

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++) {
      let value = object[Object.keys(object)[i]];
      if (typeof value === "object" && value != null) {
        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');

以下是演示:http://jsfiddle.net/a21dx6c0/

已编辑

同样,您可以找到不止一个对象

function deepSearchItems(object, key, predicate) {
        let ret = [];
        if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) {
            ret = [...ret, object];
        }
        if (Object.keys(object).length) {
            for (let i = 0; i < Object.keys(object).length; i++) {
                let value = object[Object.keys(object)[i]];
                if (typeof value === "object" && value != null) {
                    let o = this.deepSearchItems(object[Object.keys(object)[i]], key, predicate);
                    if (o != null && o instanceof Array) {
                        ret = [...ret, ...o];
                    }
                }
            }
        }
        return ret;
    }
qc6wkl3g

qc6wkl3g20#

如果您想在搜索Object时获取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的所有元素都存储在Result中,如您所见):

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

piztneat21#

另一个(有些愚蠢的)选择是利用JSON.stringify的自然递归特性,并向其传递一个替换函数,该函数在字符串化过程中在每个嵌套对象上运行:

const input = [{
  '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': {}
      }]
    }]
  }]
}];

console.log(findNestedObj(input, 'id', '1'));

function findNestedObj(entireObj, keyToFind, valToFind) {
  let foundObj;
  JSON.stringify(entireObj, (_, nestedValue) => {
    if (nestedValue && nestedValue[keyToFind] === valToFind) {
      foundObj = nestedValue;
    }
    return nestedValue;
  });
  return foundObj;
};
7d7tgy0s

7d7tgy0s22#

对我来说起作用的是这种懒惰的方法,而不是算法上的懒惰;)

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

相关问题