JS 在对象值中搜索

IT技术 javascript json search
2021-02-11 20:08:17

我有一系列类似的同类对象;

[
  {
    "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”不同)......你明白了。

我该怎么做呢?非常感谢!

6个回答

像这样的东西:

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 '));
所以我修改了我的答案以添加 a) 修剪代码(在搜索之前修剪搜索字符串)和 b) 更完整的数组对象搜索代码,以确保我们在结果集中没有重复。现在我想它会按照你想要的方式工作。请检查我更新的答案。丢弃以前的版本并在答案中使用新的 EDIT 部分下方的版本。
2021-03-18 20:08:17
为了使它不区分大小写:里面的searchFor(..)功能,更换线if(objects[i][key].indexOf(toSearch)!=-1) {if(objects[i][key].toLowerCase().indexOf(toSearch)!=-1) {和更换线toSearch = trimString(toSearch);toSearch = trimString(toSearch).toLowerCase();
2021-03-21 20:08:17
你的意思是最后有空格吗?在那种情况下,简单的修剪应该有效吗?您能否提供 toSearch 值和您尝试使用的对象值的示例(带空格)?
2021-03-24 20:08:17
稍微编辑了 for 循环。现在,如果您将 toSearch 设置为 'lo',则输出将为: [{foo="lorem"}, { foo="dolor"}]
2021-03-28 20:08:17
更新了我的答案。希望这是您想要实现的目标。
2021-04-04 20:08:17

所有其他旧答案都使用 for in 循环,现代 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 => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}
如果我将任何数字作为值传递,这将不起作用。像 [{"q":1,"r":null,"c":null},{"q":2,"r":null,"c":null},{"q":3," r":null,"c":null}]
2021-03-15 20:08:17
那么 OP 有包含的字符串。数字没有那个方法@HarshPatel
2021-03-26 20:08:17
使用@epascarello 中的这段代码,您可以找到一个对象,该对象的键包含 searchKey,但是如果您要搜索完全匹配项,您应该使用“===”而不是“includes”来更改“some”方法的测试函数: some(key => obj[key] === searchKey)
2021-04-02 20:08:17

这是一个很酷的解决方案,效果很好

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))

已编辑

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)=>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)

您是否愿意对 itme=>item 进行更多解释。它究竟是如何工作的?到目前为止,我还没有找到任何很好的解释。
2021-03-21 20:08:17
为什么var在可以const用于item变量时使用
2021-04-11 20:08:17

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

快速搜索所有关键属性中的内容,
2021-03-14 20:08:17
这很快,没有正则表达式,并检查以确保没有原型键hasOwnProperty.
2021-04-03 20:08:17

这是一个提议,它使用给定的键或对象的所有属性来搜索值。

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'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

谢谢你的回答。它完美运行,但仅当搜索值与对象数组中的值完全匹配时才有效。
2021-03-14 20:08:17
嗨尼娜,您可以增强更改a[key] === valuea[key].indexOf(value) > -1或其他使用这里。当您使用配置参数时,您可以将 indexOf 用作默认值和===可选值。
2021-04-08 20:08:17