JSでrange
Pythonのrange(配列で返すほう)をJSで書く。
function range(from, to, step) { var i, a = []; if (typeof to == "undefined") { to = from; from = 0; } if (typeof step == "undefined") step = 1; if (step == 0) throw new TypeError("range() step argument must not be zero"); if (from < to) { if (step > 0) for (i = from; i < to; i += step) a.push(i); } else { if (step < 0) for (i = from; i > to; i += step) a.push(i); } return a; }
stepの正負によって分けて、同じようなコードが二つあるのがイマイチ。
次に、stepが負の場合には逆順に配列を作るようにして.reverse()するようにした物。
function range(from, to, step) { var i, a = []; if (typeof to == "undefined") return range(0, from, step); if (typeof step == "undefined") return range(from, to, 1); if (from > to) return range(to + 1, from + 1, -step).reverse(); if (step == 0) throw new TypeError("range() step argument must not be zero"); if (step > 0) for (i = from; i < to; i += step) a.push(i); return a; }
reverseしたので速度が落ちる。+1している部分も分かりづらい。
どう書くと良いのだろう。
簡単なテスト:
function eqv(a, b) { function cmp(_, i) { return a[i] === b[i]; } return a.length == b.length && a.every(cmp); } function assert(code, value) { var ok; try { ok = eqv(eval(code), value); } catch (ex) { console.error("%s: %o", code, ex); return; } if (ok) console.log("%s: %o", code, ok); else console.error("%s: %o", code, ok) } assert("range(0)", []); assert("range(0, 0)", []); assert("range(3, 2)", []); assert("range(-1, 2, -1)", []); assert("range(3, 0)", []); assert("range(1)", [0]); assert("range(2)", [0, 1]); assert("range(0, 1)", [0]); assert("range(1, 5, 2)", [1, 3]); assert("range(-1, 2)", [-1, 0, 1]); assert("range(-1, 2, 2)", [-1, 1]); assert("range(3, 0, -1)", [3, 2, 1]);