开发者问题收集

JS 在对象值中搜索

2011-12-15
337700

我有一个类似这样的同类对象数组;

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

我该怎么做呢?提前谢谢!

3个回答

类似这样:

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 '));
techfoobar
2011-12-15

所有其他旧答案都使用 for in 循环,现代 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)));
}
epascarello
2016-11-30

这是使用现代 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));
Edison Arango
2021-03-05