for 文
私としては for
文で十分と考えます。
一応、Array.prototype.reduce
でも実装できますが…。
JavaScript
1function sample1 (inputArray, inputNumber) {
2 var matched = [], smaller = [];
3
4 for (var i = 0, len = inputArray.length, value; i < len; ++i) {
5 value = inputArray[i];
6 value < inputNumber ? smaller.push(value) : matched.push(value);
7 }
8
9 return matched.concat(smaller);
10}
11
12console.log(sample1([1, 2, 3, 4, 5, 6, 7], 4)); // [4, 5, 6, 7, 1, 2, 3]
Array.prototype.reduce
一方の配列(smaller
)をスコープ外に置けば Array.prototype.reduce
でも実装可能です。
JavaScript
1function sample2 (inputArray, inputNumber) {
2 var matched = [], smaller = [];
3
4 return inputArray.reduce(function (matched, current) {
5 current < inputNumber ? smaller.push(current) : matched.push(current);
6 return matched;
7 }, []).concat(smaller);
8}
9
10console.log(sample2([1, 2, 3, 4, 5, 6, 7], 4)); // [4, 5, 6, 7, 1, 2, 3]
クロージャとGCの扱いが微妙なのでスコープを調節するとこのように。
JavaScript
1var sample3 = (function () {
2 function reduceCallbackfn (matched, current) {
3 current < this.inputNumber ? this.smaller.push(current) : matched.push(current);
4 return matched;
5 }
6
7 return function sample3 (inputArray, inputNumber) {
8 var smaller = [];
9 return inputArray.reduce(reduceCallbackfn.bind({smaller: smaller, inputNumber: inputNumber}), []).concat(smaller);
10 }
11}());
12console.log(sample3([1, 2, 3, 4, 5, 6, 7], 4)); // [4, 5, 6, 7, 1, 2, 3]
Array.prototype.filter
Array.prototype.filter
を「4以上」と「4未満」で2回呼び出す方法もあるのですが、そうする場合は配列を2回走査する事になるのでアルゴリズム上は無駄が生じます。
配列を一度だけ回すのが美しいと考えています。
一応、filter 処理の中でもう一つの配列を作る手がありますが、処理内容は Array.prototype.reduce
と同じです。
JavaScript
1function sample3 (inputArray, inputNumber) {
2 var smaller = [];
3
4 return inputArray.filter(function (value) {
5 return value < inputNumber ? (smaller.push(value), false) : true;
6 }).concat(smaller);
7}
8console.log(sample3([1, 2, 3, 4, 5, 6, 7], 4)); // [4, 5, 6, 7, 1, 2, 3]
更新履歴
- 2017/01/31 14:27
Array.prototype.reduce
のコード追記
- 2017/02/01 00:05
Array.prototype.filter
のコード追記
Re: holism さん