JS поиск по значениям объекта - PullRequest
38 голосов
/ 15 декабря 2011

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

[
  {
    "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") ... идея понятна.

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

Ответы [ 14 ]

1 голос
/ 08 декабря 2017

Просто еще один вариант с использованием 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);
});
0 голосов
/ 31 мая 2019

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

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

//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}))
0 голосов
/ 16 декабря 2018

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

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"}
   ]}
   ];
count:
0 голосов
/ 29 августа 2016

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

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; })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...