У меня есть массив однородных объектов, как это;

[ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor", "bar" : "amet" } ] 

Я хотел бы искать значения этих объектов (не ключей) с помощью ключевого слова и возвращать массив объектов, которые содержат ключевое слово в любом из значений.

Так, например, с ключевым словом r я бы получил все объекты («baR» в объекте № 1, «loRem» в объекте № 2 и «doloR» в объекте № 3). С ключевым словом lo я получу объекты 2 и 3 («LOrem» и «doLOr»), а с a я получу объекты 1 и 3 («bAr» и «Amet»). Однако с ключевым словом foo я бы получил пустой массив, так как «foo» является ключом и не найден ни в одном из значений (в отличие от «bar») … идея понятна.

Как бы я поступил так? Заранее большое спасибо!

Что-то вроде этого:

 var objects = [ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor", "bar" : "amet" } ]; var results = []; var toSearch = "lo"; for(var i=0; i{amp}lt;objects.length; i  ) { for(key in objects[i]) { if(objects[i][key].indexOf(toSearch)!=-1) { results.push(objects[i]); } } } 

Массив результатов будет содержать все совпадающие объекты.

Если вы ищете «lo», результат будет выглядеть так:

 [{ foo="lorem", bar="ipsum"}, { foo="dolor", bar="amet"}] 

НОВАЯ ВЕРСИЯ — Добавлен код обрезки, код, чтобы избежать дублирования в наборе результатов.

 function trimString(s) { var l=0, r=s.length -1; while(l {amp}lt; s.length {amp}amp;{amp}amp; s[l] == ' ') l  ; while(r {amp}gt; l {amp}amp;{amp}amp; s[r] == ' ') r-=1; return s.substring(l, r 1); } function compareObjects(o1, o2) { var k = ''; for(k in o1) if(o1[k] != o2[k]) return false; for(k in o2) if(o1[k] != o2[k]) return false; return true; } function itemExists(haystack, needle) { for(var i=0; i{amp}lt;haystack.length; i  ) if(compareObjects(haystack[i], needle)) return true; return false; } var objects = [ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor blor", "bar" : "amet blo" } ]; function searchFor(toSearch) { var results = []; toSearch = trimString(toSearch); // trim it for(var i=0; i{amp}lt;objects.length; i  ) { for(var key in objects[i]) { if(objects[i][key].indexOf(toSearch)!=-1) { if(!itemExists(results, objects[i])) results.push(objects[i]); } } } return results; } console.log(searchFor('lo ')); 

Все остальные старые ответы используют цикл for, в современном JavaScript есть Object.keys . Объедините это с некоторыми, включает в себя, и фильтр, и это немного лучше.

 var a = [{ name: 'xyz', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }]; function filterIt(arr, searchKey) { return arr.filter(function(obj) { return Object.keys(obj).some(function(key) { return obj[key].includes(searchKey); }) }); } console.log("find 'x'", filterIt(a,"x")); console.log("find 'a'", filterIt(a,"a")); console.log("find 'z'", filterIt(a,"z")); 

Или с ES6

 function filterIt(arr, searchKey) { return arr.filter(obj ={amp}gt; Object.keys(obj).some(key ={amp}gt; obj[key].includes(searchKey))); } 

Функция search вернет все объекты, которые содержат значение, содержащее поисковый запрос.

 function search(arr, s){ var matches = [], i, key; for( i = arr.length; i--; ) for( key in arr[i] ) if( arr[i].hasOwnProperty(key) {amp}amp;{amp}amp; arr[i][key].indexOf(s) {amp}gt; -1 ) matches.push( arr[i] ); // {amp}lt;-- This can be changed to anything return matches; }; // dummy data var items = [ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor", "bar" : "amet" } ]; var result = search(items, 'lo'); // search "items" for a query value console.log(result); // print the result 

Это классное решение, которое отлично работает

 const array = [{"title":"tile hgfgfgfh"},{"title":"Wise cool"},{"title":"titlr DEytfd ftgftgfgtgtf gtftftft"},{"title":"This is the title"},{"title":"yeah this is cool"},{"title":"tile hfyf"},{"title":"tile ehey"}]; var item = array.filter(item={amp}gt;item.title.toLowerCase().includes('this')); alert(JSON.stringify(item)) 

отредактированный

 const array = [{"title":"tile hgfgfgfh"},{"title":"Wise cool"},{"title":"titlr DEytfd ftgftgfgtgtf gtftftft"},{"title":"This is the title"},{"title":"yeah this is cool"},{"title":"tile hfyf"},{"title":"tile ehey"}]; // array.filter loops through your array and create a new array returned as Boolean value given out "true" from eachIndex(item) function var item = array.filter((item)={amp}gt;eachIndex(item)); //var item = array.filter(); function eachIndex(e){ console.log("Looping each index element ", e) return e.title.toLowerCase().includes("this".toLowerCase()) } console.log("New created array that returns "true" value by eachIndex ", item) 

Как Javascripter Lv. 1 Я только что научился искать строки в объектах с помощью этого:

 function isThere( a_string, in_this_object ) { if( typeof a_string != 'string' ) { return false; } for( var key in in_this_object ) { if( typeof in_this_object[key] == 'object' || typeof in_this_object[key] == 'array' ) { if ( isThere( a_string, in_this_object[key] ) ) { return true; } } else if( typeof in_this_object[key] == 'string' ) { if( a_string == in_this_object[key] ) { return true; } } } return false; } 

Я знаю, что это далеко от совершенства, но это полезно.

Не стесняйтесь комментировать, чтобы улучшить это.

 var search(subject, objects) { var matches = []; var regexp = new RegExp(subject, 'g'); for (var i = 0; i {amp}lt; objects.length; i  ) { for (key in objects[i]) { if (objects[i][key].match(regexp)) matches.push(objects[i][key]); } } return matches; }; var items = [ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor", "bar" : "amet" } ]; search('r', items); // ["bar", "lorem", "dolor"] 

Это пропоосал, который использует ключ, если он задан, или все свойства объекта для поиска значения.

 function filter(array, value, key) { return array.filter(key ? a ={amp}gt; a[key] === value : a ={amp}gt; Object.keys(a).some(k ={amp}gt; a[k] === value) ); } var a = [{ name: 'xyz', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }]; console.log(filter(a, 'x')); console.log(filter(a, 'x', 'name')); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Вы можете использовать эту библиотеку JavaScript, DefiantJS ( http://defiantjs.com ), с помощью которой вы можете фильтровать совпадения, используя XPath на структурах JSON. Чтобы поместить это в код JS:

  var data = [ { "foo": "bar", "bar": "sit" }, { "foo": "lorem", "bar": "ipsum" }, { "foo": "dolor", "bar": "amet" } ], res1 = JSON.search( data, '//*[contains(name(), 'r')]/..' ), res2 = JSON.search( data, '//*[contains(., 'lo')]' ); /* res1 = [ { "foo": "bar", "bar": "sit" }, { "foo": "lorem", "bar": "ipsum" }, { "foo": "dolor", "bar": "amet" } ] */ /* res2 = [ { "foo": "lorem", "bar": "ipsum" }, { "foo": "dolor", "bar": "amet" } ] */ 

Вот рабочая скрипка;
http://jsfiddle.net/hbi99/2kHDZ/

DefiantJS расширяет глобальный объект методом «поиск» и возвращает массив совпадений (пустой массив, если совпадений не найдено). Вы можете попробовать запросы lib и XPath с помощью XPath Evaluator здесь:

http://www.defiantjs.com/#xpath_evaluator

Вот ответ в 100% чистом JavaScript:

 {amp}lt;html{amp}gt; {amp}lt;head{amp}gt; {amp}lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /{amp}gt; {amp}lt;title{amp}gt;{amp}lt;/title{amp}gt; {amp}lt;script type="text/javascript"{amp}gt; var mySet = [ { "foo" : "bar", "bar" : "sit" }, { "foo" : "lorem", "bar" : "ipsum" }, { "foo" : "dolor", "bar" : "amet" } ]; function queryObject(needle, set){ var results = new Array(); for(index=0;index{amp}lt;set.length;index  ){ for(key in set[index]){ if(set[index][key].indexOf(needle) {amp}gt; -1){ results.push(set[index]); } } } if(results.length){ return JSON.stringify(results); }else{ return "No match!"; } } {amp}lt;/script{amp}gt; {amp}lt;/head{amp}gt; {amp}lt;body{amp}gt; {amp}lt;form{amp}gt; {amp}lt;input type="text" id="prompt" onFocus="this.value='';" value="Type your query HERE" size="20" onKeyDown="document.getElementById('submit').disabled = false;"{amp}gt; {amp}lt;input id="submit" type="button" value="Find in Object" onClick="var prompt=document.getElementById('prompt'); if(prompt.value){document.getElementById('output').innerHTML = queryObject(prompt.value, mySet);}else{prompt.value='Type your query HERE';}" disabled="disabled"{amp}gt; {amp}lt;div id="output"{amp}gt;{amp}lt;/div{amp}gt; {amp}lt;/form{amp}gt; {amp}lt;/body{amp}gt; {amp}lt;/html{amp}gt; 

Есть, конечно, более причудливые способы обхода вашего объекта с помощью JQuery, но это основная концепция.

Ура!

* РЕДАКТИРОВАТЬ: Извините, я недостаточно внимательно прочитал ваш вопрос и изменил код так, чтобы он возвращал массив объектов по вашему запросу.

Хотя немного поздно, но более компактная версия может быть следующим:

 /** * @param {string} quickCriteria Any string value to search for in the object properties. * @param {any[]} objectArray The array of objects as the search domain * @return {any[]} the search result */ onQuickSearchChangeHandler(quickCriteria, objectArray){ let quickResult = objectArray.filter(obj ={amp}gt; Object.values(obj).some(val ={amp}gt; val?val.toString().toLowerCase().includes(quickCriteria):false)); return quickResult; } 

Он может обрабатывать ложные значения, такие как false, undefined, null и все типы данных, которые определяют метод .toString() такие как number, boolean и т. Д.

Просто еще один вариант с использованием ES6 , это то, что я использую.

 // searched keywords const searchedWord = "My searched exp"; // array of objects let posts = [ { text_field: "lorem ipsum doleri imet", _id: "89789UFJHDKJEH98JDKFD98" }, { text_field: "ipsum doleri imet", _id: "JH738H3JKJKHJK93IOHLKL" ]; // search results will be pushed here let matches = []; // regular exp for searching let regexp = new RegExp(searchedWord, 'g'); // looping throuth posts to fing the word posts.forEach((post) ={amp}gt; { if (post["text_field"].match(regexp)) matches.push(post); }); 

Мне нужно было выполнить поиск по большому объекту и вернуть адреса совпадений, а не только сами сопоставленные значения.

Эта функция ищет объект для поиска строки (или, альтернативно, использует функцию обратного вызова для выполнения пользовательской логики) и отслеживает, где значение было найдено в объекте. Это также избегает циклических ссылок.

 //Search function var locateInObject = function(obj, key, find, result, currentLocation){ if(obj === null) return; result = result||{done:[],found:{}}; if(typeof obj == 'object'){ result.done.push(obj); } currentLocation = currentLocation||key; var keys = Object.keys(obj); for(var k=0; k{amp}lt;keys.length;   k){ var done = false; for(var d=0; d{amp}lt;result.done.length;   d){ if(result.done[d] === obj[keys[k]]){ done = true; break; } } if(!done){ var location = currentLocation '.' keys[k]; if(typeof obj[keys[k]] == 'object'){ locateInObject(obj[keys[k]], keys[k], find, result, location) }else if((typeof find == 'string' {amp}amp;{amp}amp; obj[keys[k]].toString().indexOf(find) {amp}gt; -1) || (typeof find == 'function' {amp}amp;{amp}amp; find(obj[keys[k]], keys[k]))){ result.found[location] = obj[keys[k]]; } } } return result.found; } //Test data var test = { key1: { keyA: 123, keyB: "string" }, key2: { keyC: [ { keyI: "string123", keyII: 2.3 }, "string" ], keyD: null }, key3: [ 1, 2, 123, "testString" ], key4: "123string" } //Add a circular reference test.key5 = test; //Tests console.log(locateInObject(test, 'test', 'string')) console.log(locateInObject(test, 'test', '123')) console.log(locateInObject(test, 'test', function(val, key){ return key.match(/keyd/) {amp}amp;{amp}amp; val.indexOf('string') {amp}gt; -1})) 

Ниже поделились для конкретного данного свойства

 searchContent:function(s, arr,propertyName){ var matches = []; var propertyNameString=this.propertyNameToStr(propertyName); for (var i = arr.length; i--; ){ if(("" Object.getOwnPropertyDescriptor(arr[i], propertyNameString).value).indexOf(s) {amp}gt; -1) matches.push(arr[i]); } return matches; }, propertyNameToStr: function (propertyFunction) { return /.([^.;] );?s*}$/.exec(propertyFunction.toString())[1]; } 

// использование как ниже

 result=$localStorage.searchContent(cabNo,appDataObj.getAll(),function() { dummy.cabDriverName; }) 

Я нашел способ, которым вы можете искать во вложенном объекте, как и во всем, например, список учеников, у которых есть вложенный объект урока:

 var students=[{name:"ali",family:"romandeh",age:18,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]}, {name:"hadi",family:"porkar",age:48,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]}, {name:"majid",family:"porkar",age:30,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]} ]; function searchInChild(objects, toSearch){ var _finded=false; for(var i=0; i{amp}lt;objects.length; i  ) { for(key in objects[i]) { if(objects[i][key]!=null {amp}amp;{amp}amp; typeof(objects[i][key] )!="boolean" {amp}amp;{amp}amp; typeof(objects[i][key] )!="number"){ if (typeof objects[i][key] == 'object') { _finded= searchInChild(objects[i][key],toSearch); } else if(objects[i][key].indexOf(toSearch)!=-1) { _finded=true; } } } } return _finded; } function findNested(objects, toSearch) { var _results=[]; for(var i=0; i{amp}lt;objects.length; i  ) { for(key in objects[i]) { if(objects[i][key]!=null {amp}amp;{amp}amp; typeof(objects[i][key] )!="boolean" {amp}amp;{amp}amp; typeof(objects[i][key] )!="number"){ if (typeof objects[i][key] == 'object') { if(searchInChild(objects[i][key],toSearch)){ _results.push(objects[i]); } } else if(objects[i][key].indexOf(toSearch)!=-1) { _results.push(objects[i]); } } } } return _results; } $('.quickSearch').on('click',function(){ var _inputSeach=$('#evertingSearch').val(); if(_inputSeach!=''){ var _finded=findNested(students,_inputSeach); $('.count').html(_finded.length);} }); 
 {amp}lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;html{amp}gt; {amp}lt;head{amp}gt; {amp}lt;/head{amp}gt; {amp}lt;body{amp}gt; {amp}lt;span{amp}gt; {amp}lt;pre{amp}gt;{amp}lt;code{amp}gt; var students=[{name:"ali",family:"romandeh",age:18,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]}, {name:"hadi",family:"porkar",age:48,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]}, {name:"majid",family:"rezaeiye",age:30,curse:[ {lesson1:"arabic"}, {lesson2:"english"}, {lesson3:"history"} ]} ]; {amp}lt;/code{amp}gt;{amp}lt;/pre{amp}gt; {amp}lt;span{amp}gt; {amp}lt;input id="evertingSearch" placeholder="Search on students" /{amp}gt; {amp}lt;input type="button" class="quickSearch" value="search" /{amp}gt; {amp}lt;lable{amp}gt;count:{amp}lt;/lable{amp}gt;{amp}lt;span class="count"{amp}gt;{amp}lt;/span{amp}gt; {amp}lt;/body{amp}gt; {amp}lt;/html{amp}gt; 

Сегодня столкнулся с этой проблемой, и с помощью модифицированной версии предоставленного epascarello кода добился цели, потому что в этой версии возникли проблемы, когда объект содержал некоторые значения, отличные от строк (например, число логических значений).

 console.log('find: ', findIn(arrayOfObjects, searchKey)); const findIn = (arr, searchKey) ={amp}gt; { return arr.filter(obj ={amp}gt; Object.keys(obj).some(key ={amp}gt; { if (typeof obj[key] === 'string') { return obj[key].includes(searchKey); } }) ); }; 
 search(searchText) { let arrayOfMatchedObjects = arrayOfAllObjects.filter(object ={amp}gt; { return JSON.stringify(object) .toString() .toLowerCase() .includes(searchText); }); return arrayOfMatchedObjects; } 

Это может быть очень простой, простой, быстрый и понятный поиск для некоторых из вас, как я.