2009-11-30 10 views
12

Ho un oggetto JavaScript come questo:Cerca un oggetto JavaScript

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

Ora voglio per cercare questo oggetto JavaScript nel browser. La ricerca di "FC" dovrebbe darmi qualcosa del genere:

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

Come fare questo veloce? Esistono librerie JavaScript per questo?

+0

Cosa è un oggetto JSON? Vuoi dire che hai una stringa JSON * *? –

+0

Ha un oggetto JavaScript, ovviamente. Presumo che abbia detto che è JSON perché ha chiesto a un server come JSON o JSONP. :-) – Nosredna

risposta

7

Sebbene sia possibile farlo in JavaScript, underscore.js è una buona libreria per gestire questa roba. Probabilmente potresti farlo andare con "pluck" e "each".

La cosa bella di underscore.js è che utilizza le chiamate integrate del browser quando esistono.

+1

puoi mostrare anche il codice? – JerryGoyal

+0

il link è rotto – crh225

+0

Il collegamento è stato corretto. –

0

Il modo semplice per eseguire questa operazione è semplicemente iterare su ogni proprietà dell'oggetto e applicare una funzione di test (in questo caso, value.contains("FC")).

Se si desidera che funzioni più rapidamente, è necessario implementare una sorta di memorizzazione nella cache (che potrebbe essere popolata in background prima di qualsiasi query), o magari precalcolare il risultato di varie funzioni di test popolari.

+0

Mi piacerebbe andare più veloce di O (n). Ho pensato a qualcosa come http://en.wikipedia.org/wiki/Trie, ma non voglio scriverlo da solo se non è necessario. –

+0

@Juri, sei disposto a pre-elaborare l'oggetto in una struttura diversa o vuoi utilizzare l'oggetto così com'è? Ovviamente c'è un costo per la conversione da una struttura all'altra. Ne varrebbe la pena, probabilmente, se avessi intenzione di fare molte ricerche sugli stessi dati. – Nosredna

+0

@Nosredna: Sì, la pre-elaborazione è assolutamente possibile. –

12

come si potrebbe utilizzare jLinq (progetto personale)

http://Hugoware.net/Projects/jLinq

Opere come LINQ, ma per JSON e permette di estendere e modificarlo comunque lo si voglia. Esistono già numerosi metodi precostituiti per controllare valori e intervalli.

+0

Questo è un grande progetto. – Nosredna

+0

Questo è un grande progetto e una bellissima pagina web per questo. Ho visto un tipo che potresti voler correggere ... "Leggi The Documenation" – Nosredna

+0

@Nosredna - Grazie, controllerò! – Hugoware

0

Si potrebbe fare questo con le espressioni regolari eseguiti contro una stringa JSON serializzato:

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

Non ho ancora testato la parte del ciclo di questo, ma il Regex sembra funzionare bene per me con semplici prove in firebug.

+0

lol, grazie per la correzione, Crescent :) – JasonWyatt

+1

... quindi ora l'OP ha due problemi ... – vtortola

3

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

È ottimizzato per la ricerca O (logn) veloce e l'ordinamento su tabelle grandi (migliaia di righe) in JS.

Contrariamente all'iterazione di matrice, su cui si basa la maggior parte delle risposte, jOrder utilizza gli indici per filtrare i dati. Solo per darti un'idea, la ricerca a testo libero su una tabella di 1000 righe completa circa 100 volte più velocemente dell'iterazione. Più grande è il tavolo, migliore è il rapporto che ottieni.

Tuttavia jOrder non può elaborare il formato dei dati di esempio. Ma se si ri-formato in questo modo:

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

è possibile ottenere i risultati desiderati in primo luogo la creazione di un tavolo jOrder:

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

E poi eseguire una ricerca su di esso:

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

E otterrete esattamente le due file necessarie. Questo è tutto.

-2

Per quanto riguarda AngularJS, si può fare questo:

var item = "scope-ng-model"; 

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

Questo imposta solo la proprietà di un oggetto Scope AngularJS, non ricerca nulla. –

+0

Questo non risolve il problema dell'op. – captainrad

5

Vedendo come se le uniche risposte utili sono stati riferimento a librerie di terze parti -, ecco la soluzione javascript nativo. Per tutti quelli che vogliono solo poche righe di codice, piuttosto che una pila:

La funzione:

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; 
} 

Originario .map() funzione:

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; 
} 

vostro alloggio:

(scremato dall'abject pubblicato):

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

Per l'utilizzo:

(Questo cercherà l'array myObject.elems per un 'nome' Matching 'FC')

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

Il risultato - controllare la console:

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