我有两个dim数组,它看起来像这样:
var a = [[1,2,3],[4,5,6],[7,8,9]];
我想写一个迭代器,每次调用它时只返回一个值。
iterator(); //returns 1
iterator(); //returns 2
iterator(); //returns 3
我试过这样的方法:
function iterator() {
var a = [[1,2,3],[4,5,6],[7,8,9]];
var i, j;
return function() {
for (var i = 0; i < a.length; i++) {
var b = a[i];
for (var j = 0; j < b.length; j++) {
return a[i][j];
}
}
}
};
var a = iterator();
a(); //1
a(); //1
a(); //1
总是返回第一个元素。
我可以试试这个:
function iterator() {
var a = [[1,2,3],[4,5,6],[7,8,9]];
var i = 0, j = 0;
return function() {
for (; i < a.length; i++) {
var b = a[i];
for (; j < b.length; j++) {
return a[i][j];
}
}
}
};
Also not works.
但是如果我尝试这个:
function test() {
var a = [1,2,3,4,5], i = 0;
return function() {
while (i < a.length) {
return a[i++];
}
}
}
var a = test();
a(); //1
a(); //2
a(); //3
很好。
这里有什么不同?如何使循环工作?
对我来说另一个明显的问题是边界。当我到达数组边界时,我应该如何停止?
对于第二次元,您可以使用简单的if
来测试j
function iterator() {
var a = [[1,2,3],[4,5,6],[7,8,9]];
var i = 0, j = 0;
return function() {
for (; i < a.length; i++) {
var b = a[i];
if (j < b.length){
return a[i][j++];
}
j = 0;
}
return undefined; // reached when there is no value left
}
};
在这种情况下为什么需要循环呢?无论如何,你都在有效地使数组扁平化。你可以只增加索引和边界检查:
function iterator() {
var a = [[1,2,3],[4,5,6],[7,8,9]], i = 0, j = 0;
return function() {
if (j >= a[i].length) { j = 0; i++; }
if (i >= a.length) { j = 0; i = 0; }
snippet.log( a[i][j++] );
}
};
var x = iterator();
x(); x(); x(); x(); x(); x(); x(); x(); x(); x();
x(); x(); x(); x(); x(); x(); x(); x(); x(); x();
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
扩展标准特性通常不是一个好主意,但对于一个教学示例,我将例外。对于实际使用,我建议实现您自己的类。
大意
Array.prototype.beginIterator = function()
{
var counter = 0;
return function()
{
if (counter<=this.length) return this[counter++];
else return undefined;
};
}
然后你可以像这样迭代:
var a = [3,1,4,1,5];
var it = a.beginIterator();
for (var i=it(); i!=undefined; i=it())
{
alert(i);
}
这目前只适用于一维数组,但它可以应用于其他数组或对象的任何逻辑。
多维(任何)解决方案:
下面的迭代器允许任意维数组的任意组合:
Array.prototype.beginIterator = function()
{
var counter = 0;
var iterators = null;
return function()
{
val = undefined;
if (iterators!=null)
{
val = iterators();
if (val!==undefined) return val;
else
{
iterators = null;
counter++;
}
}
while (counter <=this.length)
{
if (!(this[counter] instanceof Array)) return this[counter++];
else
{
iterators = this[counter++].beginIterator();
val = iterators();
if (val!==undefined) return val;
}
}
return undefiend;
};
}
使用示例:
var a = [3,[3,5,7],4,[1,[2,5,8]],5];
var it = a.beginIterator();
for (var i=it(); i!=undefined; i=it())
{
alert(i);
}