我有一系列同类对象,如此;
[
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
},
{
"foo" : "dolor",
"bar" : "amet"
}
]
我想用关键字搜索这些对象的值(而不是键),并在任何值中返回包含关键字的对象数组。
因此,例如,使用关键字r
,我将获得所有对象(对象#1中的“baR”,对象#2中的“loRem”和对象#3中的“doloR”)。使用关键字lo
,我会得到对象2和3(“LOrem”和“doLOr”),a
,我会得到对象1和3,(“bAr”和“Amet” )。然而,使用关键字foo
,我会得到一个空数组,因为“foo”是一个键,并且在任何值中都找不到(不像“bar”)......你明白了。< / p>
我该怎么做呢?非常感谢提前!
答案 0 :(得分:47)
这样的事情:
var objects = [
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
},
{
"foo" : "dolor",
"bar" : "amet"
}
];
var results = [];
var toSearch = "lo";
for(var i=0; i<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 < s.length && s[l] == ' ') l++;
while(r > l && 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<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<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 '));
答案 1 :(得分:32)
所有其他旧答案都使用for循环,现代JavaScript有Object.keys
。将它与some,includes和filter相结合,它更好一些。
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 => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}
答案 2 :(得分:5)
search
函数将返回包含包含搜索查询的值的所有对象
function search(arr, s){
var matches = [], i, key;
for( i = arr.length; i--; )
for( key in arr[i] )
if( arr[i].hasOwnProperty(key) && arr[i][key].indexOf(s) > -1 )
matches.push( arr[i] ); // <-- 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
答案 3 :(得分:4)
作为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;
}
我知道远非完美,但它很有用。
随意发表评论以改善这一点。
答案 4 :(得分:3)
var search(subject, objects) {
var matches = [];
var regexp = new RegExp(subject, 'g');
for (var i = 0; i < 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"]
答案 5 :(得分:3)
这是一个propoosal,它使用键给定,或者使用对象的所有属性来搜索值。
function filter(array, value, key) {
return array.filter(key
? a => a[key] === value
: a => Object.keys(a).some(k => 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'));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 6 :(得分:2)
这是现代 Javascript 的一种简洁方式:
var objects = [
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
},
{
"foo" : "dolor blor",
"bar" : "amet blo"
}
];
const query = "lo";
const filteredItems = objects.filter(item => `${item.foo} ${item.bar}`.includes(query));
答案 7 :(得分:2)
这是一个很好的解决方案
$test
<强> EDITED 强>
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=>item.title.toLowerCase().includes('this'));
alert(JSON.stringify(item))
&#13;
答案 8 :(得分:2)
您可以使用此javascript lib,DefiantJS(http://defiantjs.com),您可以使用它在JSON结构上使用XPath过滤匹配。把它放在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使用方法“search”扩展全局对象,并返回一个匹配的数组(如果没有找到匹配则返回空数组)。您可以在此处使用XPath Evaluator尝试lib和XPath查询:
答案 9 :(得分:2)
以下是100%PURE JavaScript中的答案:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
<script type="text/javascript">
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<set.length;index++){
for(key in set[index]){
if(set[index][key].indexOf(needle) > -1){
results.push(set[index]);
}
}
}
if(results.length){
return JSON.stringify(results);
}else{
return "No match!";
}
}
</script>
</head>
<body>
<form>
<input type="text" id="prompt" onFocus="this.value='';" value="Type your query HERE" size="20" onKeyDown="document.getElementById('submit').disabled = false;">
<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">
<div id="output"></div>
</form>
</body>
</html>
当然,使用JQuery有更多奇特的方法遍历您的对象,但这是基本概念。
干杯!
*编辑:抱歉,我没有仔细阅读您的问题,并修改了代码以返回您请求的对象数组。
答案 10 :(得分:1)
使用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) => {
if (post["text_field"].match(regexp)) matches.push(post);
});
答案 11 :(得分:1)
虽然有点晚,但更紧凑的版本可能如下:
target_link_libraries(demo antlr4-runtime)
它可以处理虚假值,例如false,undefined,null以及定义/**
* @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 => Object.values(obj).some(val => val?val.toString().toLowerCase().includes(quickCriteria):false));
return quickResult;
}
方法的所有数据类型,如.toString()
等。
答案 12 :(得分:1)
现代JavaScript ?
const objects = [
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
},
{
"foo" : "dolor blor",
"bar" : "amet blo"
}
];
const keyword = 'o';
const results = objects.filter(object => Object.values(object).some(i => i.includes(keyword)));
console.log(results);
// results [{ foo: 'lorem', bar: 'ipsum' },{ foo: 'dolor blor', bar: 'amet blo' }]
答案 13 :(得分:0)
以下为特定属性
分享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) > -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; })
答案 14 :(得分:0)
我找到了一种可以像所有搜索一样在嵌套对象中进行搜索的方法,例如具有嵌套课程对象的学生列表:
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<objects.length; i++) {
for(key in objects[i]) {
if(objects[i][key]!=null && typeof(objects[i][key] )!="boolean" && 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<objects.length; i++) {
for(key in objects[i]) {
if(objects[i][key]!=null && typeof(objects[i][key] )!="boolean" && 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);}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<span>
<pre><code>
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"}
]}
];
</code></pre>
<span>
<input id="evertingSearch" placeholder="Search on students" />
<input type="button" class="quickSearch" value="search" />
<lable>count:</lable><span class="count"></span>
</body>
</html>
答案 15 :(得分:0)
我需要对一个大对象执行搜索,并返回匹配项的地址,而不仅仅是匹配值本身。
此函数在对象中搜索字符串(或者使用回调函数执行自定义逻辑),并跟踪在对象中找到该值的位置。它还避免了循环引用。
//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<keys.length; ++k){
var done = false;
for(var d=0; d<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' && obj[keys[k]].toString().indexOf(find) > -1) || (typeof find == 'function' && 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(/key\d/) && val.indexOf('string') > -1}))
答案 16 :(得分:0)
今天就解决了这个问题,并使用了epascarello提供的代码的修改版本就可以解决问题,因为当对象包含字符串以外的其他值(例如许多布尔值)时,该版本会遇到麻烦。
console.log('find: ', findIn(arrayOfObjects, searchKey));
const findIn = (arr, searchKey) => {
return arr.filter(obj =>
Object.keys(obj).some(key => {
if (typeof obj[key] === 'string') {
return obj[key].includes(searchKey);
}
})
);
};
答案 17 :(得分:0)
search(searchText) {
let arrayOfMatchedObjects = arrayOfAllObjects.filter(object => {
return JSON.stringify(object)
.toString()
.toLowerCase()
.includes(searchText);
});
return arrayOfMatchedObjects;
}
对于像我这样的某些人来说,这可能是非常简单,容易,快速且易于理解的搜索功能。
答案 18 :(得分:0)
我创建了一个易于使用的库,该库可以完全满足您的需求:ss-search
import { search } from "ss-search"
const data = [
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
},
{
"foo" : "dolor",
"bar" : "amet"
}
]
const searchKeys = ["foor", "bar"]
const searchText = "dolor"
const results = search(data, keys, searchText)
// results: [{ "foo": "dolor", "bar": "amet" }]
答案 19 :(得分:0)
您可以使用lodash的 _filter 方法:
return _filter((item) => item.name.includes("fo"),tempObjectHolder);
答案 20 :(得分:0)
简单
const objects = [
{
"foo" : "bar",
"bar" : "sit",
"date":"2020-12-20"
},
{
"foo" : "lorem",
"bar" : "ipsum",
"date":"2018-07-02"
},
{
"foo" : "dolor",
"bar" : "amet",
"date":"2003-10-08"
},
{
"foo" : "lolor",
"bar" : "amet",
"date":"2003-10-08"
}
];
const filter = objects.filter(item => {
const obj = Object.values(item)
return obj.join("").indexOf('2003') !== -1
})
console.log(filter)