2012-02-23 61 views
14

我有一个javascript对象,我想递归 搜索它以查找包含特定值的任何属性。搜索具有特定值的属性的JavaScript对象?

我与已经作压缩工作,并且不那么容易通过跟踪的JavaScript。

背景

我使用Bing地图AJAX SDK。它有能力添加额外的瓷砖层。每个tilelayer都有一个tilesource对象,它指定了tile URL的URI格式。

我跑进其中tilesource URI创建一次,并缓存的问题。因此,我无法动态更改每个请求的URL参数(例如,根据一天中的时间更改瓦片叠加层的颜色)。

请注意,此行为与Google的Map API和WP7的Bing Maps API不同,后者允许您为每个磁贴请求动态创建URL。

缓存URI被查找,和两个特定的参数被替换,则URI用于获取瓷砖。

由于这是JavaScript的,我想找到缓存的URI,并用功能取代它,而不是那动态构建URI,并返回。

我并不需要这样做每次运行时,只是想和属性被缓存在那里的想法,所以我可以编写代码来hax0r它。

原始的问题

如果我设置的URI像“floobieblaster”一定的价值,当我设置一个断点,可我搜索了JavaScript对象递归“floobieblaster”,并获得所存储的属性值?

修改以添加

我寻找对象显示为具有圆形的参考,从而任何递归代码很可能引起一个计算器。

是否有任何编辑器/调试技巧,我可以利用?

+0

我想我有可能倾倒的对象出来JSON和搜索这种方式。也许有更好的办法? - 没有。看起来物体具有圆形结构。 – Alan 2012-02-23 22:57:10

+0

Crockford的库(请参阅cycle.js)https://github.com/douglascrockford/JSON-js支持将循环对象编码和解码为json(+ jsonpath)。您可以按照您的建议串行化和搜索,或者稍微更改代码以直接实现目标。 – davin 2012-02-23 23:50:10

回答

20

一些简单的像这应该工作:

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

    } 

} 

如果执行searchObj(testObj, 'testValue');它会记录下到控制台:

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

很明显,你可以代替你想无论console.log,或者向searchObj函数添加回调参数以使其更加可重用。

编辑:添加了query参数,允许您指定要搜索,当你调用该函数的值。

+6

+1,但为了防止在[[Prototype]]链上搜索对象,应该包含'hasOwnProperty'测试。考虑测试'typeof obj [key] =='function''。 – RobG 2012-02-24 00:26:14

2

这是我的解决方案,它将给定的字符串/值与正则表达式测试匹配并返回匹配的数组。它不是递归的,但是你已经从你的问题中删除了这个。

这是我的答案在下面的线程: Search a JavaScript object

相同的原则,如其他人所说 - 搜索给定值的对象,在寻找这个解决方案中的任何一个。

功能:

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

你的对象:

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

有关使用方法:

(这将搜索您myObject.elems阵列的 '名称' 匹配 'FC')

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

结果 - 检查您的控制台:

[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] 

如果你想完全匹配你只需在三元语句更改正则表达式的基本价值相匹配。 即

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

该函数将在对象中搜索。它会将搜索查询与对象的每个属性相匹配。当您需要在多维对象中搜索时,这非常有用 花费数小时后,我从Google的AngularJS项目中获得了此代码。

/* 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; 
} 
}; 
+1

这显然处理递归结构,而接受的答案没有。 – Automatico 2017-11-09 21:27:56

1

这里是一个更方便的随时可以去静态方法根据布莱恩的做法:

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

对于对象

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

将导致

["test", "test2.test2a"] 
0

我编辑布莱恩唐宁答案打印分层HY深对象:

function searchObj (obj, query, prefix /*not to be set*/) { 
    prefix = prefix || "---"; 
    var printKey; 

    for (var key in obj) { 
     var value = obj[key]; 

     if (typeof value === 'object') { 
      if (searchObj(value, query, prefix + "|---")) { 
       console.log(prefix + ' ' + key); 
       printKey = true; 
      } 
     } 

     if (value === query) { 
      console.log(prefix + ' ' + key + ' = ' + value); 

      return true; 
     } 
    } 

    return printKey; 
} 

然后,运行searchObj(testObj, 'testValue');

0
//example from the Binance API. 
//They return a ticker object with ALL of their currency pairs 
//that contain the current price of each pair. 
//We want to allow users to enter in a currency pair, 
//and return the current ask price of the currency. E.g., 
//users are asking for something that we do not know if it 
// exists until the ticker object is returned. Therefore, we 
//must search for a property in the object, if it exists, 
//return the value of the found property. 

let symbol = 'LTCBTC'; 
if (symbol in ticker) { 
    console.log(ticker[symbol]); 
} else { 
console.log('symbol not found or not supported'); 
} 
//This example uses the javascript property accessor to access 
//the property once we've verified it is in the 
//object [js property accessors][1] and the in 
//operator [js in property][2] 
相关问题