web-dev-qa-db-fra.com

Recherche Javascript dans un objet JSON

J'avais une chaîne/un objet JSON dans mon application. 

{"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"}
]}

J'avais une boîte de filtrage dans mon application, et lorsque je tape un nom dans cette boîte, nous devons filtrer l'objet et afficher le résultat.

Par exemple, si l'utilisateur tape "nom" et lance la recherche, nous devons alors rechercher les noms complets dans l'objet JSON et renvoyer le tableau, comme s'il s'agissait d'une recherche MySQL ...

Ma question est de filtrer l'objet JSON avec une chaîne et de retourner le tableau ....

32
ramesh

Vous pouvez simplement parcourir le tableau et trouver les correspondances:

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]);
    }
}
33
McGarnagle

Si votre question est la suivante: existe-t-il une fonction intégrée qui effectuera la recherche pour vous, alors non, il n'y en a pas. En gros, vous parcourez le tableau en utilisant String#indexOf ou une expression régulière pour tester les chaînes.

Pour la boucle, vous avez au moins trois choix:

  1. Une vieille boucle for ennuyeuse.

  2. Sur les environnements compatibles ES5 (ou avec un shim), Array#filter .

  3. Parce que vous utilisez jQuery, jQuery.map .

Exemple ennuyeux de boucle for:

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

Où vous appelez cela avec obj.list en tant que source et le fragment de nom souhaité en tant que name.

Ou, s'il y a une chance qu'il y ait des entrées vides ou des entrées sans nom, remplacez la valeur if par:

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

Array#filter exemple:

function search(source, name) {
    var results;

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

Et encore une fois, s'il y a une chance qu'il y ait des entrées vides (par exemple, undefined, par opposition à manquant; filter sautera manquant entrées), remplacez le retour interne par:

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

Exemple jQuery.map (ici, je suppose que jQuery = $ comme d'habitude; changez $ en jQuery si vous utilisez 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;
}

(Et encore, ajoutez entry && entry.name && dedans si nécessaire.)

31
T.J. Crowder

Utilisez PaulGuo 's jSQL , une base de données semblable à SQL utilisant JavaScript. Par exemple:

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

J'ai adapté regex pour travailler avec JSON.

Tout d'abord, stringify l'objet JSON. Ensuite, vous devez stocker les débuts et les longueurs des sous-chaînes correspondantes. Par exemple:

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

Pour une chaîne JSON, cela fonctionne exactement de la même manière (à moins que vous ne cherchiez explicitement des virgules et des accolades, auquel cas je recommanderais de transformer au préalable votre objet JSON avant d’exécuter une expression rationnelle (par exemple, pensez:, {,}).

Ensuite, vous devez reconstruire l'objet JSON. L'algorithme que j'ai créé le fait en détectant la syntaxe JSON en remontant récursivement de l'index de correspondance. Par exemple, le pseudo-code pourrait ressembler à ceci:

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

Avec ces informations, il est possible d’utiliser regex pour filtrer un objet JSON afin de renvoyer la clé, la valeur et la chaîne d’objets parent.

Vous pouvez voir la bibliothèque et le code que j'ai créés à http://json.spiritway.co/

0
mikewhit

Si vous effectuez cette opération à plusieurs endroits de votre application, il serait logique d'utiliser une base de données JSON côté client, car la création de fonctions de recherche personnalisées appelées par array.filter () est complexe et moins gérable que la solution de remplacement.

Découvrez ForerunnerDB qui vous fournit un système de base de données JSON côté client très puissant et comprend un langage de requête très simple pour vous aider à faire exactement ce que vous recherchez:

// 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"}
]
*/

Disclaimer: Je suis le développeur de ForerunnerDB.

0
Rob Evans