2015-05-23 3 views
2

Мне нужно проверить, содержит ли глубокий объект определенное значение и возвращает true/false. Этот объект не ограничен количеством вложенных объектов или массивов, которые он может иметь.Как проверить, имеет ли значение глубокого объекта значение

// sample object 
{ 
    "id": 2, 
    "name": "Mann Anderson", 
    "documents": [ 
    { 
     "score": 36, 
     "documentTitle": "Document Title: 8397640", 
     "source": "RAND Data" 
    } 
    ], 
    "emailAddresses": [ 
    "[email protected]" 
    ] 
} 

И я использую эту рекурсивную функцию для итерации по объекту:

function deepQuery(value, q){ 
    if(_.isArray(value) || _.isPlainObject(value)) { 
    _.each(value, function(v, k) { 
     return deepQuery(v, q); 
    }); 
    } else if(value.toString().toLowerCase().indexOf(q) !== -1) { 
    console.log(true); 
    return true; 
    } 
} 

функция, кажется, работает (the console.log(true) появляется, когда ожидается), но я только получаю undefined как результат функции ,

Сначала я думал, что это было потому, что я не возвращал рекурсивный вызов deepQuery(), но, как вы можете видеть, это не тот случай.

+0

Очень сильно связан с https://stackoverflow.com/questions/4271919/return-from-inner-function-in-javascript и другие (https://stackoverflow.com/questions/2509635/javascript-how-to-call-outer-functions- return-from-inner-function), может быть дублирующимся. –

+0

Это, вероятно, дубликат, в смысле есть много ответов на SO, дающие шаблоны для глубоких поисков, но я думаю, что ответ, объясняющий ошибку, может быть интересным. –

ответ

2

Там:

_.each(value, function(v, k) { 
    return deepQuery(v, q); 
}); 

вы только возвращения из обратного вызова вы передаете _.each, а не от функции. И, конечно, возвращение только вернет значение для первого более глубокого вызова, а не для первого положительного поиска.

Изменить его

var v = false; 
_.each(value, function(v, k) { 
    v |= deepQuery(v, q); 
}); 
return v; 

или лучше: использовать старые добрые for петли, чтобы полностью избежать этой проблемы (и, чтобы избежать продолжать итерации, когда найдено совпадение):

function deepQuery(value, q){ 
    if (_.isArray(value)) { 
    for (var i=0; i<value.length; i++) { 
     if (deepQuery(value[i], q)) return true; 
    } 
    } else if(_.isPlainObject(value)) { 
    for (var k in value) { 
     if (deepQuery(value[k], q)) return true; 
    } 
    } else if(value.toString().toLowerCase().indexOf(q) !== -1) { 
    return true; 
    } 
} 
+0

Это исправлено. Спасибо. Можете ли вы объяснить операцию '| ='? –

+0

@Ryancrosser 'a | = b' является' a = a | b': он делает true, если b истинно (это уже не так). –

+0

Получил это. Спасибо. –

Смежные вопросы