2009-11-30 6 views
12

Ich habe ein JavaScript-Objekt wie folgt aus:ein JavaScript-Objekt Suche

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

Jetzt möchte ich auf diesem JavaScript-Objekt im Browser suchen. Die Suche nach "FC" sollte mir so etwas geben:

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

Wie geht das schnell? Gibt es dafür JavaScript-Bibliotheken?

+0

Was ist ein JSON-Objekt? Du meinst, du hast einen JSON * string *? –

+0

Er hat natürlich ein JavaScript-Objekt. Ich nehme an, er sagte, dass es JSON ist, weil er einen Server nach JSON oder JSONP gefragt hat. :-) – Nosredna

Antwort

7

Obwohl Sie es in geraden JavaScript tun könnten, underscore.js ist eine gute Bibliothek, um dieses Zeug zu behandeln. Mit "pluck" und "each" könntest du es wahrscheinlich in Gang bringen.

Schöne Sache über underscore.js ist, dass es die integrierten Aufrufe des Browsers verwendet, wenn sie existieren.

+1

können Sie den Code auch anzeigen? – JerryGoyal

+0

der Link ist unterbrochen – crh225

+0

Link wurde behoben. –

0

Der einfache Weg, dies zu tun, besteht darin, einfach über jede Eigenschaft des Objekts zu iterieren und eine Testfunktion auf sie anzuwenden (in diesem Fall value.contains("FC")).

Wenn Sie möchten, dass es schneller geht, müssen Sie entweder eine Art Zwischenspeicherung implementieren (die vor jeder Abfrage im Hintergrund ausgefüllt werden könnte) oder das Ergebnis verschiedener beliebter Testfunktionen vorberechnen.

+0

Ich würde gerne schneller gehen als O (n). Ich dachte über etwas wie http://en.wikipedia.org/wiki/Trie nach, aber ich möchte das nicht alleine schreiben, wenn es nicht notwendig ist. –

+0

@Juri, sind Sie bereit, das Objekt in eine andere Struktur vorzuverarbeiten, oder möchten Sie das Objekt unverändert verwenden? Es gibt natürlich Kosten, um von einer Struktur in eine andere zu konvertieren. Es wäre es vielleicht wert, wenn Sie viele Suchen mit denselben Daten durchführen würden. – Nosredna

+0

@Nosredna: Ja, Vorverarbeitung ist absolut möglich. –

12

Sie vielleicht gefallen jLinq (persönliches Projekt)

http://Hugoware.net/Projects/jLinq

Works wie LINQ verwenden, aber für JSON und ermöglicht es Ihnen, es zu erweitern und ändern Sie es, wie Sie wollen zu. Es gibt bereits eine Reihe vorgefertigter Methoden, um Werte und Bereiche zu überprüfen.

+0

Das ist ein großartiges Projekt. – Nosredna

+0

Das ist ein großartiges Projekt und eine schöne Webseite dafür. Ich habe einen Typ gesehen, den Sie vielleicht korrigieren möchten ... "Lesen Sie die Dokumenation" – Nosredna

+0

@Nosredna - Danke, ich werde es überprüfen! – Hugoware

0

Sie können dies tun, mit regulären Ausdrücken gegen eine serialisierte JSON-String ausgeführt:

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

ich die Schleife nicht Teil davon getestet haben, aber die Regex scheint für mich gut mit einfachen Tests zu arbeiten in Brandstifter.

+0

lol, danke für den Fix, Crescent :) – JasonWyatt

+1

... so jetzt OP hat zwei Probleme ... – vtortola

3

Versuchen Sie jOrder. http://github.com/danstocker/jorder

Es ist optimiert für schnelle O (Logn) Suche und Sortierung auf großen (Tausende von Zeilen) Tabellen in JS.

Im Gegensatz zur Array-Iteration, auf der die meisten Antworten basieren, verwendet jOrder Indizes zum Filtern von Daten. Um Ihnen eine Idee zu geben, ist die Freitextsuche in einer Tabelle mit 1000 Zeilen ungefähr 100 Mal schneller als die Iteration. Je größer der Tisch, desto besser das Verhältnis.

Allerdings kann jOrder das Format Ihrer Beispieldaten nicht verarbeiten. Aber wenn Sie neu formatiert es wie folgt aus:

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

Sie können die gewünschten Ergebnisse erzielen, indem zunächst eine Jörder Tabelle einrichten:

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

Und dann eine Suche auf es ausgeführt wird:

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

Und Sie erhalten genau die zwei Reihen, die Sie benötigten. Das ist es.

-2

In Bezug auf AngularJS, können Sie dies tun:

var item = "scope-ng-model"; 

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

Dies setzt nur die Eigenschaft eines AngularJS Scope-Objekts, es sucht nichts. –

+0

Dies betrifft nicht das Problem des op. – captainrad

5

sehen, als ob den einzigen hilfreichen Antworten haben Bibliotheken von Drittanbietern wurde Referenzierung - hier ist Ihre Mutter Javascript-Lösung. Für alle, die ein paar Zeilen Code, anstatt einen Stapel nur will:

Die Funktion:

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

Eine native .map() Funktion:

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

Ihr Objekt:

(Mager von Ihrem geposteten abject):

Für Nutzung:

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

Das Ergebnis (Dies wird Ihre myObject.elems Array für einen 'Namen' passende 'FC' suchen) - überprüfen Sie Ihre Konsole:

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