如何在未知深度的物体中找到价值?

时间:2014-01-30 12:56:38

标签: javascript object

首先,我将尝试解释情况。

我有类别的对象数组,其中包含更深层次的对象,如下所示:

/*
    Categories

    Object variables legend:
    n - name, u - ID, p - category picture,
    s - sub categories
*/
    var Categories = [
        {n:'Category',u:1,p:'http://#',s:[{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:6,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:7,s:[],items:['sku','sku2']}],items:['sku','sku2']},{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[]},{n:'Sub sub category 2',u:6,s:[]},{n:'Sub sub category 3',u:7,s:[]}]},{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[]},{n:'Sub sub category 2',u:6,s:[]},{n:'Sub sub category 3',u:7,s:[]}]}],items:['sku','sku2']},
        {n:'Category',u:2,p:'http://#',s:[{n:'Sub category',u:8,s:[{n:'Sub sub category',u:9,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:10,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:11,s:[],items:['sku','sku2']}],items:['sku','sku2']}],items:['sku','sku2']},
        {n:'Category',u:3,p:'http://#',s:[{n:'Sub category',u:12,s:[{n:'Sub sub category',u:13,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:14,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:15,s:[],items:['sku','sku2']}],items:['sku','sku2']}],items:['sku','sku2']}
    ];

所以基本上是子类别,可以有无限深度..现在我需要编写一个函数,它将返回项目的值,当我提供ID(这是你)时。

我应该如何实现这一点,如果我知道深度是什么,我可以写多个'for'循环,但我不知道。

是否有某种过滤功能我可以适应这项任务?

3 个答案:

答案 0 :(得分:2)

第一个观察结果是您的Categories对象略有不规则。 Categories是一个看似数组的常规对象,而子类是所有数组。

这样可以更轻松地使用:

var Categories = [
        {n:'Category',u:1,p:'http://#',s:[{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:6,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:7,s:[],items:['sku','sku2']}],items:['sku','sku2']},{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[]},{n:'Sub sub category 2',u:6,s:[]},{n:'Sub sub category 3',u:7,s:[]}]},{n:'Sub category',u:4,s:[{n:'Sub sub category',u:5,s:[]},{n:'Sub sub category 2',u:6,s:[]},{n:'Sub sub category 3',u:7,s:[]}]}],items:['sku','sku2']},
        {n:'Category',u:2,p:'http://#',s:[{n:'Sub category',u:8,s:[{n:'Sub sub category',u:9,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:10,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:11,s:[],items:['sku','sku2']}],items:['sku','sku2']}],items:['sku','sku2']},
        {n:'Category',u:3,p:'http://#',s:[{n:'Sub category',u:12,s:[{n:'Sub sub category',u:13,s:[],items:['sku','sku2']},{n:'Sub sub category 2',u:14,s:[],items:['sku','sku2']},{n:'Sub sub category 3',u:15,s:[],items:['sku','sku2']}],items:['sku','sku2']}],items:['sku','sku2']}
    ]

递归解决方案:

function searchRecursive(needle, haystack) {
  for (var i=0; i<haystack.length; i++) {
    if (haystack[i].u === needle) return haystack[i];
    var search = searchRecursive(needle, haystack[i].s);
    if (search) return search;
  }
  return null;
}

// Usage:
searchRecursive(10, Categories) // Object {n: "Sub sub category 2", u: 10, s: Array[0], items: Array[2]}

非递归解决方案:

function search(needle, haystack) {
  var queue = haystack.slice();

  while (queue.length) {
    var current = queue.shift();
    if (current.u === needle) return current;
    queue = queue.concat(current.s);
  }
  return null;
}

// Usage:
search(10, Categories) // Object {n: "Sub sub category 2", u: 10, s: Array[0], items: Array[2]}

答案 1 :(得分:1)

Array ObjectsObject Objects。您可能需要更改:

var Categories = {

为:

var Categories = [

然后你需要迭代地遍历你的Array

function getU( obj, u ) {
    var result = null;
    for (var i = 0, len = obj.length; i < len; i++) {
        if (obj[i].u === u) {
            result = obj[i];
            break;
        }
    }
    if( result === null ) {
        result = getU( obj[ i ].s, u)
    }
    return result;
}

并且第一次称它为:

getU( Categories, u);

u是您要查找的ID。

答案 2 :(得分:1)

现在您的格式更好(标准化数据更多),您的搜索变得更加容易:

function getU(obj, u){
    for (var i = 0, r; i < obj.length && !r; i++){
        if (obj[i].u == u) return obj[i];
        r = getU(obj[i].s, u);
    }
    return r;
}

所以,for example

getU(Categories, 6)
// returns: {"n":"Sub sub category 2","u":6,"s":[],"items":["sku","sku2"]}
getU(Categories, 14)
// returns: {"n":"Sub sub category 2","u":14,"s":[],"items":["sku","sku2"]}

// and of course (upper-most node)
getU(Categories, 1)
// returns {"n":"Category","u":1,"p":"http://#","s":[{"n":"Sub category","u":4,"s":[{"n":"Sub sub category","u":5,"s":[],"items":["sku","sku2"]},{"n":"Sub sub category 2","u":6,"s":[],"items":["sku","sku2"]},{"n":"Sub sub category 3","u":7,"s":[],"items":["sku","sku2"]}],"items":["sku","sku2"]},{"n":"Sub category","u":4,"s":[{"n":"Sub sub category","u":5,"s":[]},{"n":"Sub sub category 2","u":6,"s":[]},{"n":"Sub sub category 3","u":7,"s":[]}]},{"n":"Sub category","u":4,"s":[{"n":"Sub sub category","u":5,"s":[]},{"n":"Sub sub category 2","u":6,"s":[]},{"n":"Sub sub category 3","u":7,"s":[]}]}],"items":["sku","sku2"]}