2012-06-22
配列深くても全部フラットにするArray.flatten
どーもこんちわ。ECMAScript 5th Edition とか JavaScript 1.8あたり。
JavaScriptの場合、本当の意味での「多次元配列」っていうのは無いとおもうから*1「何次元配列」っていうのはなんか違和感があるんだけど、まぁいいのかな。似た実装の他言語でやったときに「配列の配列」って言ってた気がしたのはジャグ配列かぁ
flatten function
うまくうごいてそう。全部greedyにやる場合の呼び名あるといいなぁ。levelある方が特別なのかな
var flatten = function (ary) { return ary.reduce(function (p, c) { return Array.isArray(c) ? p.concat(flatten(c)) : p.concat(c); }, []); }; // console.log(flatten([[[2], 0], [1, 3], [4, 6, [5, 7]]])); // [2, 0, 1, 3, 4, 6, 5, 7]https://gist.github.com/2975364
Array.isArray
過激すぎるかも。Array-likeかどうかで見てもいいかもしれない
flatten(c)
のとこはお好みでarguments.callee
化してもいいかもだけど、ES5 strict原理主義者にウガーって襲われるかもしれない。そんなひといればだけど :-b
Qiita
なんか盛り上がってた。スマートだしaplly()
の第二引数が配列取るのをうまくつかっててかっこいい。kanemu@github++!
var ary = [[1,2,3,4,5,6,7],[8,9,10],[11,12]]; var ary2 = Array.prototype.concat.apply([],ary); /* ary2 == [1,2,3,4,5,6,7,8,9,10,11,12]; */no title
どこから出てきたコードだろ。Rubyとかの使ったことないけど、Array#flatten(1)
になるのかな
投下してきた
貪欲(greedy)にどこまでもflattenする版
えーごもどきだよ
Ten.Array.flatten
Tenのもarguments.callee(o)
してgreedyタイプ
/* Ten.Array */ Ten.Array = { flatten: function(arr) { var ret = []; (function(arr) { for (var i = 0; i < arr.length; i++) { var o = arr[i]; if (Ten.Array.isArray(o)) { arguments.callee(o); } else { ret.push(o); } } })(arr); return ret; }, //... isArray: function(o) { return (o instanceof Array || (o && typeof(o.length) === 'number' && typeof(o) != 'string' && !o.nodeType)); }http://s.hatena.ne.jp/js/Ten/Ten.js
スタック使ってて効率いいかもしれない。Ten.Array.isArray
はArray-likeなarguments
とかNodeList
でもtrue
返すようになってて柔軟性がある。ただ、!o.nodeType
評価してるのにちゅうい
あわせてよみたい
MDN
reduceじゃなくていい気g(ry
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); }); // flattened is [0, 1, 2, 3, 4, 5]Example: Flatten an array of arrays - Array reduce method - MDN
これだと機能的に同じなArray.prototype.concat.aplly([], ary)
の方が利用ハードル低いしスマート
id:javascripter
ぐぐって見てみたらprototype
拡張してる以外ほぼおんなじだった
2008年・・さすが。このワンライナーはJS 1.8のExpression closuresを使ってるから、いまのところFirefox系以外だと動かない気がする。
Array.prototype.flatten=function()this.reduce(function(a,b)a.concat((b instanceof Array)?b.flatten():b),[]);Arrayを拡張(flatten,max,min,sum,uniq,first,last) - 素人がプログラミングを勉強していたブログ
こんな感じに直せば動く
Array.prototype.flatten = function () { return this.reduce(function (a, b) { return a.concat(b instanceof Array ? b.flatten() : b); }, []); };
ワンライナーにしてはちょっと長い・・
下のブロックのやつは大抵のモダンブラウザで動くはず。変わったインデントだなぁ
Array.prototype.flatten=function(){ return this.reduce( function(a,b){ if(b instanceof Array){ return a.concat(b.flatten()); }else{ return a.concat(b); } } ,[]); }Arrayを拡張(flatten,max,min,sum,uniq,first,last) - 素人がプログラミングを勉強していたブログ
JavaScript Guru id:javascripter++!