2009-11-30 13 views
12

Tengo un objeto JavaScript como esto:Buscar un objeto JavaScript

[{ 
    name : "soccer", 
    elems : [ 
     {name : "FC Barcelona"}, 
     {name : "Liverpool FC"} 
    ] 
}, 
{ 
    name : "basketball", 
    elems : [ 
     {name : "Dallas Mavericks"} 
    ] 
}] 

Ahora quiero buscar en este objeto de JavaScript en el navegador. La búsqueda de "FC" debería darme algo como esto:

[ 
    {name : "FC Barcelona"}, 
    {name : "Liverpool FC"} 
] 

¿Cómo hacer esto rápido? ¿Hay alguna biblioteca de JavaScript para esto?

+0

Lo es un objeto JSON? ¿Quiere decir que tiene una cadena JSON *? –

+0

Él tiene un objeto de JavaScript, por supuesto. Supongo que dijo que es JSON porque le pidió a un servidor que lo haga como JSON o JSONP. :-) – Nosredna

Respuesta

7

Aunque puede hacerlo en JavaScript, underscore.js es una buena biblioteca para manejar este tipo de cosas. Probablemente puedas ponerlo en funcionamiento con "desplume" y "cada uno".

Lo bueno de underscore.js es que usa las llamadas integradas del navegador cuando existen.

+1

¿Puedes mostrar el código también? – JerryGoyal

+0

el enlace está roto – crh225

+0

El enlace ha sido reparado. –

0

La manera directa de hacerlo es simplemente iterar sobre cada propiedad del objeto y aplicarles una función de prueba (en este caso, value.contains("FC")).

Si quiere que sea más rápido, debe implementar algún tipo de almacenamiento en caché (que podría llenarse con entusiasmo en el fondo delante de cualquier consulta), o quizás precalcular el resultado de varias funciones de prueba populares.

+0

Me gustaría ir más rápido que O (n). Pensé en algo como http://en.wikipedia.org/wiki/Trie, pero no quiero escribir esto por mi cuenta si no es necesario. –

+0

@Juri, ¿está dispuesto a preprocesar el objeto en una estructura diferente, o desea utilizar el objeto tal como está? Hay un costo, por supuesto, para convertir de una estructura a otra. Valdría la pena, posiblemente, si hiciera muchas búsquedas con los mismos datos. – Nosredna

+0

@Nosredna: Sí, el preprocesamiento es absolutamente posible. –

12

te pueden gustar usando jLinq (proyecto personal)

http://Hugoware.net/Projects/jLinq

Obras como LINQ, pero para JSON y que le permite ampliar y modificarlo sin embargo desea. Ya hay un montón de métodos preprogramados para verificar valores y rangos.

+0

Ese es un gran proyecto. – Nosredna

+0

Es un gran proyecto y una hermosa página web para él. Vi un tipo que podría querer corregir ... "Lea la documentación" – Nosredna

+0

@Nosredna - ¡Gracias, lo verificaré! – Hugoware

0

Se puede hacer esto con expresiones regulares realizados contra una cadena JSON serializado:

var jsonString = "[{ name : \"soccer\", elems : [ {name : \"FC Barcelona\"}" 
    +", {name : \"Liverpool FC\"}]},{name : \"basketball\",elems : [" 
    +"{name : \"Dallas Mavericks\"} ]}]"; 

var pattern = /\s*([\w\d_]+)\s*:\s*((\"[^\"]*(your pattern here)[^\"]*\")|(\'[^\']*(your pattern here)[^\']*\'))\s*/g; 

var foundItems = []; 
var match; 
while(match = pattern.exec(jsonString)){ 
    foundItems.push(match[0]); 
} 

var foundJSON = "[{" + foundItems.join("}, {") + "}]"; 
var foundArray = eval(foundJSON);

No he probado la parte de bucle de esto, pero la expresión regular parece estar funcionando bien para mí con pruebas sencillas en Firebug.

+0

lol, gracias por la corrección, Crescent :) – JasonWyatt

+1

... entonces ahora OP tiene dos problemas ... – vtortola

3

Pruebe jOrder. http://github.com/danstocker/jorder

Está optimizado para una rápida búsqueda de O (logn) y clasificación en tablas grandes (miles de filas) en JS.

A diferencia de la iteración de matriz, en la que se basan la mayoría de las respuestas, jOrder usa índices para filtrar datos. Solo para darle una idea, la búsqueda de texto libre en una tabla de 1000 filas completa aproximadamente 100 veces más rápido que la iteración. Cuanto más grande es la mesa, mejor es la proporción que obtienes.

Sin embargo, jOrder no puede procesar el formato de los datos de muestra. Pero si vuelve a formato de esta manera:

var teams = 
[ 
{ sport : "soccer", team: "FC Barcelona" }, 
{ sport : "soccer", team: "Liverpool FC" }, 
{ sport : "basketball", team : "Dallas Mavericks"} 
] 

, usted puede obtener los resultados deseados por primera creación de una mesa jOrder:

var table = jOrder(teams) 
    .index('teams', ['team'], { grouped: true, ordered: true, type: jOrder.text }); 

Y a continuación, ejecutar una búsqueda en él:

var hits = table.where([{ team: 'FC' }], { mode: jOrder.startof }); 

Y obtendrá exactamente las dos filas que necesitaba. Eso es.

-2

En lo que respecta a AngularJS, usted puede hacer esto:

var item = "scope-ng-model"; 

(angular.element('form[name="myForm"]').scope())[item] = newVal; 
+0

Esto solo establece la propiedad de un objeto AngularJS Scope, no busca nada. –

+0

Esto no resuelve el problema de la operación. – captainrad

5

Al ver como si las únicas respuestas votos han sido referencia a bibliotecas de terceros - aquí está su solución javascript nativo. Para cualquier persona que sólo quiere unas pocas líneas de código en lugar de una pila:

La función:

Array.prototype.findValue = function(name, value){ 
    var array = map(this, function(v,i){ 
     var haystack = v[name]; 
     var needle = new RegExp(value); 
     // check for string in haystack 
     // return the matched item if true, or null otherwise 
     return needle.test(haystack) ? v : null; 
    }); 
    return array; 
} 

Un .map() función nativa:

map = function(array, mapFunction) { 
     var newArray = new Array(array.length); 
     for(var i = 0; i < array.length; i++) { 
     newArray[i] = mapFunction(array[i]); 
     } 
     return newArray; 
} 

Su objeto:

(desnatada de su abyecto publicado):

myObject = { 
     name : "soccer", 
     elems : [ 
      {name : "FC Barcelona"}, 
      {name : "Liverpool FC"} 
     ] 
    }, 
    { 
     name : "basketball", 
     elems : [ 
      {name : "Dallas Mavericks"} 
     ] 
    } 

Para el uso:

(Esto buscará la matriz myObject.elems para un 'nombre' juego 'FC')

var matched = myObject.elems.findValue('name', 'FC'); 
console.log(matched); 

El resultado - comprobar su consola:

[Object, Object, findValue: function] 
0: Object 
name: "FC Barcelona" 
__proto__: Object 
1: Object 
name: "Liverpool FC" 
__proto__: Object 
length: 2 
__proto__: Array[0] 
Cuestiones relacionadas