Rechercher un objet javascript pour une propriété avec une valeur spécifique?

J'ai un objet javascript, et je veux le rechercher récursivement pour trouver les propriétés qui contiennent une valeur spécifique.

Le javascript avec lequel je travaille a été minifié et n'est pas si facile à suivre.

Contexte

J'utilise le SDK Bingo Maps AJAX. Il a la possibilité d'ajouter d'autres couches de tuiles. Chaque tilelayer possède un objet tilesource, qui spécifie le format URI pour l'URL de la tuile.

J'ai rencontré un problème où l'URI de tilesource est créé une fois, et mis en cache. Ainsi, je ne peux pas modifier dynamiquement les paramètres de l'URL (par exemple, pour changer les couleurs de la superposition de carreaux en fonction de l'heure) pour chaque demande.

Notez que ce comportement est différent de l'API Map de Google et de l'api de Bing Maps pour WP7, qui vous permettent de créer dynamiquement l'URL pour chaque demande de mosaïque.

L'URI en cache est recherché, et deux paramètres spécifiques sont remplacés, puis l'URI est utilisé pour récupérer le carreau.

Comme il s'agit de javascript, j'aimerais trouver l'URI en cache, et le remplacer par une fonction qui, à la place, crée dynamiquement l'URI et le renvoie.

Je n'ai pas besoin de faire cela chaque temps d'exécution, je veux juste et une idée de l'endroit où la propriété est mise en cache, donc je peux écrire un code pour l'avoir.

Question originale

Si j'ai configuré l'URI à une valeur telle que "floobieblaster", lorsque j'ai configuré un point d'arrêt, puis-je rechercher l'objet javascript de façon récursive pour "floobieblaster" et obtenir la propriété qui stocke cette valeur?

Modifier pour ajouter

L'objet que je recherche semble avoir une référence circulaire, donc tout code récursif entraînera vraisemblablement un flux de stackover.

Y a-t-il des astuces d'éditeur / débogueur que je pourrais utiliser?

Quelque chose de simple comme celui-ci devrait fonctionner:

var testObj = { test: 'testValue', test1: 'testValue1', test2: { test2a: 'testValue', test2b: 'testValue1' } } function searchObj (obj, query) { for (var key in obj) { var value = obj[key]; if (typeof value === 'object') { searchObj(value, query); } if (value === query) { console.log('property=' + key + ' value=' + value); } } } 

Si vous exécutez searchObj(testObj, 'testValue'); Il va se connecter ce qui suit à la console:

 property=test value=testValue property=test2a value=testValue 

De toute évidence, vous pouvez remplacer la console.log par ce que vous voulez ou ajouter un paramètre de rappel à la fonction searchObj pour la rendre plus réutilisable.

EDIT: Ajout du paramètre de query qui vous permet de spécifier la valeur que vous souhaitez rechercher lorsque vous appelez la fonction.

Voici ma solution, elle correspond à la chaîne / valeur donnée avec un test regex et renvoie le tableau correspondant. Ce n'est pas récursif, mais vous avez supprimé ceci de votre question.

Ceci résulte de ma réponse au sujet suivant: Recherchez un objet JavaScript

Les mêmes principes, comme d'autres l'ont suggéré – recherche d'un objet pour la valeur donnée, pour quiconque recherche cette solution.

La fonction:

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

Votre objet:

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

Pour l'utilisation:

(Cela recherchera votre tableau myObject.elems pour un «nom» correspondant à «FC»)

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

Le résultat – vérifiez votre console:

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

Si vous vouliez une correspondance exacte, vous modifiez simplement le regex dans l'énoncé ternaire à une correspondance de valeur de base. c'est à dire

 v[name] === value ? v : null 

Cette fonction recherchera dans Object. Il correspondra à la requête de recherche avec les objets de chaque propriété. Ceci est utile lorsque vous devez rechercher dans un objet multidimensionnel Après avoir passé des heures, j'ai obtenu ce code du projet AngularJS de Google.

 /* Seach in Object */ var comparator = function(obj, text) { if (obj && text && typeof obj === 'object' && typeof text === 'object') { for (var objKey in obj) { if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) && comparator(obj[objKey], text[objKey])) { return true; } } return false; } text = ('' + text).toLowerCase(); return ('' + obj).toLowerCase().indexOf(text) > -1; }; var search = function(obj, text) { if (typeof text == 'string' && text.charAt(0) === '!') { return !search(obj, text.substr(1)); } switch (typeof obj) { case "boolean": case "number": case "string": return comparator(obj, text); case "object": switch (typeof text) { case "object": return comparator(obj, text); default: for (var objKey in obj) { if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) { return true; } } break; } return false; case "array": for (var i = 0; i < obj.length; i++) { if (search(obj[i], text)) { return true; } } return false; default: return false; } }; 

Voici une méthode statique plus pratique et prête à l'emploi basée sur l'approche de Bryan:

 /** * Find properties matching the value down the object tree-structure. * Ignores prototype structure and escapes endless cyclic nesting of * objects in one another. * * @param {Object} object Object possibly containing the value. * @param {String} value Value to search for. * @returns {Array<String>} Property paths where the value is found. */ getPropertyByValue: function (object, value) { var valuePaths; var visitedObjects = []; function collectValuePaths(object, value, path, matchings) { for (var property in object) { if ( visitedObjects.indexOf(object) < 0 && typeof object[property] === 'object') { // Down one level: visitedObjects.push( object); path = path + property + "."; collectValuePaths( object[property], value, path, matchings); } if (object[property] === value) { // Matching found: matchings.push( path + property); } path = ""; } return matchings; } valuePaths = collectValuePaths( object, value, "", []); return valuePaths; } 

Pour un objet

 var testObj = { test: 'testValue', test1: 'testValue1', test2: { test2a: 'testValue', test2b: 'testValue1' } } 

aura pour résultat

 ["test", "test2.test2a"]