2012-05-21 21 views
30

Tenía una cadena/objeto JSON en mi aplicación.Búsqueda de Javascript dentro de un objeto JSON

{"list": [ 
    {"name":"my Name","id":12,"type":"car owner"}, 
    {"name":"my Name2","id":13,"type":"car owner2"}, 
    {"name":"my Name4","id":14,"type":"car owner3"}, 
    {"name":"my Name4","id":15,"type":"car owner5"} 
]} 

tenía una caja de filtro en mi solicitud, y al escribir un nombre en esa caja, tenemos que filtrar el objeto y mostrar el resultado.

Por ejemplo, si el "nombre" tipos de usuario y resultados de búsqueda, entonces tenemos que buscar nombres completos en el objeto JSON y devolver la matriz, al igual que una búsqueda de MySQL ...

Mi pregunta es filtre el objeto JSON con una cadena y devuelva la matriz ....

+3

lo has necesitado hasta ahora con la búsqueda? te ayudamos con el código, no te proporcionamos uno. – Joseph

+7

SO es para hacer * preguntas *. ¿Cuál es tu pregunta? –

+0

posible duplicado de [use jQuery's find() en el objeto JSON] (http://stackoverflow.com/questions/4992383/use-jquerys-find-on-json-object) y [JSON encuentra en JavaScript] (http://stackoverflow.com/q/1946165/575527) – Joseph

Respuesta

30

Se podía recorrer la matriz y encontrar las coincidencias:

var results = []; 
var searchField = "name"; 
var searchVal = "my Name"; 
for (var i=0 ; i < obj.list.length ; i++) 
{ 
    if (obj.list[i][searchField] == searchVal) { 
     results.push(obj.list[i]); 
    } 
} 
29

Si su pregunta es, ¿hay alguna cosa incorporada que haga la búsqueda por usted, entonces no, no hay. Básicamente recorre la matriz usando String#indexOf o regular expression para probar las cadenas.

Para el bucle, que tienen al menos tres opciones:

  1. Un viejo aburrido for bucle.

  2. En entornos habilitados para ES5 (o con una cuña), Array#filter.

  3. Porque está utilizando jQuery, jQuery.map.

viejo aburrido ejemplo for bucle:

function search(source, name) { 
    var results = []; 
    var index; 
    var entry; 

    name = name.toUpperCase(); 
    for (index = 0; index < source.length; ++index) { 
     entry = source[index]; 
     if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) { 
      results.push(entry); 
     } 
    } 

    return results; 
} 

Donde que se dice que con obj.list como source y el fragmento deseado como nombre name.

O si hay alguna posibilidad de que hay entradas en blanco o entradas sin nombres, cambiar el if a:

 if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) { 

Array#filter ejemplo:

function search(source, name) { 
    var results; 

    name = name.toUpperCase(); 
    results = source.filter(function(entry) { 
     return entry.name.toUpperCase().indexOf(name) !== -1; 
    }); 
    return results; 
} 

Y de nuevo, si alguna posibilidad de que no están en blanco entradas (por ejemplo, undefined, en oposición a la falta; filter omitirán entradas faltantes), cambie el retorno interno a:

 return entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1; 

jQuery.map ejemplo (aquí Asumo jQuery = $ como suele ser el caso; $ cambiar a jQuery si está usando noConflict):

function search(source, name) { 
    var results; 

    name = name.toUpperCase(); 
    results = $.map(source, function(entry) { 
     var match = entry.name.toUpperCase().indexOf(name) !== -1; 
     return match ? entry : null; 
    }); 
    return results; 
} 

(Y de nuevo, añadir entry && entry.name && allí si es necesario.)

+0

Creo que esta respuesta es un poco más detallada que la aceptada. – Neophile

+0

Confundido sobre por qué 'source' se está utilizando en la última función donde' $ .map' se está utilizando, ya que 'source' ni siquiera se usa en esa función' search', ¿cuál es el punto del parámetro para ¿eso? –

+0

Creo que olvidó pasar 'fuente' a la función jQuery' $ .map' aquí. de lo contrario, no estás mapeando nada.Además, 'fuente' necesita ser una matriz para ser mapeada, mientras que' fuente' en este caso es un 'objeto' no una matriz, por lo que deberá pasar primero a' $ .makeArray'. –

1

Uso PaulGuo 's jSQL, un SQL como base de datos usando javascript. Por ejemplo:

var db = new jSQL(); 
db.create('dbname', testListData).use('dbname'); 
var data = db.select('*').where(function(o) { 
    return o.name == 'Jacking'; 
}).listAll(); 
-1

He adaptado Regex para que funcione con JSON.

Primero, stringify el objeto JSON. Luego, debe almacenar los inicios y las longitudes de las subcadenas coincidentes. Por ejemplo:

"matched".search("ch") // yields 3 

para una cadena JSON, esto funciona exactamente de la misma (a menos que usted está buscando explícitamente comas y corchetes en cuyo caso te recomiendo transformar algunas antes de su objeto JSON antes de realizar expresiones regulares (es decir, pensar:, {,}).

A continuación, debe reconstruir el objeto JSON. El algoritmo que creé lo hace al detectar la sintaxis JSON retrocediendo recursivamente desde el índice del partido. Por ejemplo, el pseudo código podría verse como sigue:

find the next key preceding the match index, call this theKey 
then find the number of all occurrences of this key preceding theKey, call this theNumber 
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times 
return this object called parentChain 

Con esta información, es posible usar regex para filtrar un objeto JSON para devolver la clave, el valor y la cadena de objetos padre.

Se puede ver la biblioteca y el código de mi autoría en http://json.spiritway.co/

0

Si usted está haciendo esto en más de un lugar en su aplicación tendría sentido utilizar una base de datos JSON en el cliente porque la creación de funciones de búsqueda personalizada que get array.filter() es complicado y menos fácil de mantener que la alternativa.

Salida ForerunnerDB que le proporciona un potente sistema de base de datos JSON del lado del cliente e incluye un lenguaje de consulta muy simple para ayudarle a hacer exactamente lo que busca:

// Create a new instance of ForerunnerDB and then ask for a database 
var fdb = new ForerunnerDB(), 
    db = fdb.db('myTestDatabase'), 
    coll; 

// Create our new collection (like a MySQL table) and change the default 
// primary key from "_id" to "id" 
coll = db.collection('myCollection', {primaryKey: 'id'}); 

// Insert our records into the collection 
coll.insert([ 
    {"name":"my Name","id":12,"type":"car owner"}, 
    {"name":"my Name2","id":13,"type":"car owner2"}, 
    {"name":"my Name4","id":14,"type":"car owner3"}, 
    {"name":"my Name4","id":15,"type":"car owner5"} 
]); 

// Search the collection for the string "my nam" as a case insensitive 
// regular expression - this search will match all records because every 
// name field has the text "my Nam" in it 
var searchResultArray = coll.find({ 
    name: /my nam/i 
}); 

console.log(searchResultArray); 

/* Outputs 
[ 
    {"name":"my Name","id":12,"type":"car owner"}, 
    {"name":"my Name2","id":13,"type":"car owner2"}, 
    {"name":"my Name4","id":14,"type":"car owner3"}, 
    {"name":"my Name4","id":15,"type":"car owner5"} 
] 
*/ 

responsabilidad: yo soy el desarrollador de ForerunnerDB.

+0

Parece genial pero no relevante – atilkan

-2

Puede probar esto:

function search(data,search) { 
    var obj = [], index=0; 
    for(var i=0; i<data.length; i++) { 
     for(key in data[i]){ 
     if(data[i][key].toString().toLowerCase().indexOf(search.toLowerCase())!=-1) { 
       obj[index] = data[i]; 
       index++; 
       break; 
     } 
    } 
    return obj; 
} 
console.log(search(obj.list,'my Name')); 
Cuestiones relacionadas