遍历所有节点并在Javascript中生成键和值

时间:2015-01-12 22:10:14

标签: javascript traversal

给定JSON结构

var json = {
  'a': {
    'a1': ['a1a', 'a1b', 'a1c'],
    'a2': ['a2a', 'a2b'],
    'a3': []
  },
  'b': {
    'b1': ['b1a', 'b1b', 'b1c', 'b1d'],
    'b2': ['b2a', 'b2b'],
  },
  'c': ['c1', 'c2'],
  'd': {
    'd1': ['d1a', 'd1b', 'd1c'],
    'd2': []
  },
  'e': ['e1', 'e2'],
  'f': [
    'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10'
  ]
};

使用Javascript如何将其遍历到 yield 所有键和值的数组?换句话说,如果不遍历外部存储并在遍历时附加到它,如何返回整个节点键和值集的数组?

例如在Python中我可能会使用生成器。所以也许我应该问,我如何在Javascript中使用生成器?

使用jQuery的Javascript示例:

function traverse(jsonObj) {
  if( typeof jsonObj == "object" ) {
    $.each(jsonObj, function(k,v) {
      traverse(v);
    });
  }
  else {
    // how can I yield this value instead?
    console.log(jsonObj)
  }
}

我的预期输出是所有键和值的数组:

['a', 'a1', 'a1a', 'a1b', 'a1c', 'a2', 'a2a', 'a2b'] // ... and so on

2 个答案:

答案 0 :(得分:3)

ECMAScript 6有generators。所以你可以把函数写成

function *traverse(value) {
  if (typeof value === "object") {
    var isArray = Array.isArray(value);
    for (var prop in value) {
        if (!isArray) yield prop;
        yield* traverse(value[prop]);
    }
  }
  else {
    yield value;
  }
}

并将其用作:

var obj = {
  'a': {
    'a1': ['a1a', 'a1b', 'a1c'],
    'a2': ['a2a', 'a2b'],
    'a3': []
  }
};

console.log(Array.from(traverse(obj)));

DEMO via 6to5


但如果没有本地生成器,它也没有太大的不同:

function traverse(value, result) {
  result = result || [];
  if (typeof value === "object") {
    var isArray = Array.isArray(value);
    for (var prop in value) {
      if (!isArray) result.push(prop);
      traverse(value[prop], result);
    }
  }
  else {
    result.push(value);
  }
  return result;
}

console.log(traverse(obj));

答案 1 :(得分:0)

标准的javascript模式是传入处理函数:

function traverse(jsonObj, receive) {
    if (typeof jsonObj == "object") {
        if (Array.isArray(jsonObj)) {
            // Don't want to output the keys for arrays
            $.each(jsonObj, function (k, v) {
                traverse(v, receive);
            });

        } else {
            $.each(jsonObj, function (k, v) {
                traverse(k, receive);
                traverse(v, receive);
            });
        }
    } else {
        receive(jsonObj);
    }
}

然后是一些示例代码,它选择将每个产生的对象添加到数组中。

var myArray = [];
traverse(myObject, function(jsonObj) { 
                      myArray.push(jsonObj); 
                });

这是一个工作示例,它不是推送到数组,而是显示HTML中的每个项目: http://jsfiddle.net/9u3zrjes/1/