Skip to content

Instantly share code, notes, and snippets.

@ethertank
Last active March 30, 2021 01:56
Show Gist options
  • Save ethertank/4411565 to your computer and use it in GitHub Desktop.
Save ethertank/4411565 to your computer and use it in GitHub Desktop.
前に書いた ruby やらなんやらのメソッドを js に移植したコードのおまとめ。多分色々問題があるので来世でチェックする。
(function(AP) {
AP.fill || (AP.fill = function() {
if (arguments.length === 0) return this;
for (var r = this.slice(), i = arguments[1] || 0, l = (arguments[2] + arguments[1] || this.length - arguments[1] + 1) || this.length; i < l; ++i) {
r[i] = arguments[0];
}
return r;
});
AP.insert || (AP.insert = function(idx) {
if (typeof idx !== 'number') throw TypeError('"Array.insert" method\'s first argument must be a integer number.');
if (arguments.length < 2 || idx >= this.length) return this;
var argIdx = (idx < 0) ? Math.abs(idx) + 1 : idx,
len = arguments.length,
a = this.slice(),
r = a.slice(0, argIdx),
i = 1;
a.slice(0, argIdx);
for (; i < len; ++i) r.push(arguments[i]);
return r.concat(a.slice(argIdx, a.length));
});
AP.grep || (AP.grep = function(p) {
return this.filter(function(elm) {
if (typeof elm === "string" && elm.match(p)) return elm;
});
});
AP.flatten || (AP.flatten = function() {
return this.reduce(function(a, b) {
return a.concat(b instanceof Array ? b.flatten() : b);
}, []);
});
AP.transpose || (AP.transpose = function() {
if (!this.length) return [];
if (this[0] instanceof Array) {
var tlen = this.length,
dlen = this[0].length,
newA = new Array(dlen);
} else {
throw new Error(
"Arrar.prototype.transpose: " +
"Give me Two-dimensional array."
);
}
for (var i = tlen; i--;) {
if (this[i].length !== dlen)
throw new Error(
"Array.prototype.transpose: " +
"Index Error! This method can not process jug array."
);
}
for (var i = 0; i < dlen; ++i) {
newA[i] = [];
for (var j = 0, l = tlen; j < l; j++) {
newA[i][j] = this[j][i];
}
}
return newA;
});
AP.uniq || (AP.uniq = function() {
for (var i = 0, l = this.length, r = []; i < l; ++i)
r.indexOf(this[i]) === -1 && r.push(this[i]);
return r;
});
AP.count || (AP.count = function(e) {
for (var i = 0, l = this.length, r = 0; i < l; ++i)
if(this[i] === e) r++;
return r;
});
// uniq2 未テスト
/*
AP.uniq2 || (AP.uniq2 = function() {
var o = {}, i = 0, l = this.length, r = [], v;
for(; i < l; ++i) {
v = this[i];
o[v] = v;
}
for(i in o) r.push(o[i]);
return r;
});
*/
// 配列要素が全て数値でなくてはならない
/*
AP.max || (AP.max = function() {
return Math.max.apply(null, this);
});
*/
// 配列要素が全て数値でなくてはならない
/*
AP.min || (AP.min = function() {
return Math.min.apply(null, this);
});
*/
})(Array.prototype);
// fill
/* syntax *//*
[Array].fill(val [, start[, length]]);
val : セットする値
start : 配列のどの位置から値を書き換えるか
length : start の位置からからいくつ書き換えるか
*/
/* Ruby の fill *//*
"配列の、指定された範囲すべてに val をセットします。"
"二番目の 形式で length が省略された時は配列の終りまでの長さを意味します。"
"指定された部分配列が元の配列の範囲を越える時は長さを自動的に拡張し、拡張した部分を val で初期化します。"
-- http://www.ruby-lang.org/ja/old-man/html/Array.html#fill
*/
/* memo *//*
・Ruby v1.6の仕様に基づいて実装。1.7、1.8 だと…シンタックスどうすっかなコレ…って感じ。
 第四引数をブーリアンにして、第一引数に指定した関数をそのまま突っ込むか評価用とするかを切り替える…とか?
・作ってはみたけど、どういう時に使うのか、適切な用途がさっぱり分からん。
 分からんとダメよね(- ∀ - )
*/
/* test */
console.log("-----------------------------");
var a;
a = [].fill();
console.log(typeof a + "," + (a instanceof Array) + "," + a.length);// object, true, 0
a = [1, 2, 3, 4].fill("x");
console.log(a + ", " + typeof a + ", " + (a instanceof Array) + ", " + a.length); // x,x,x,x, object, true, 4
a = [1, 2, 3, 4].fill("x", 1);
console.log(a + ", " + typeof a + ", " + (a instanceof Array) + ", " + a.length); // 1,x,x,x, object, true, 4
a = [1, 2, 3, 4].fill("x", 0, 4);
console.log(a + ", " + typeof a + ", " + (a instanceof Array) + ", " + a.length); // x,x,x,x, object, true, 4
a = [1, 2, 3, 4].fill("x", 1, 4);
console.log(a + ", " + typeof a + ", " + (a instanceof Array) + ", " + a.length); // 1,x,x,x,x, object, true, 5
a = [[1, 2], [5, 6]].fill([3, 4], 1);
console.log(a + ", " + typeof a + ", " + (a instanceof Array) + ", " + a.length); // 1,2,3,4, object, true, 2
// insert
/* syntax *//*
[Array].insert(index,value[, value, value...]);
*/
// 配列の指定位置(index)の直前(負の値の場合はindexの直後)にvalueを挿入した配列を返す。
// check
var a = [1, 2, 5];
var b = a.insert(2, 3, 4);
var br = "<br />";
document.write(
"b : " + b + br +
typeof b + " / " + (b instanceof Array) + " / " + b.length + br +
"a : " + a + "(非破壊チェック)"
);
// error check
try {
[1,3].insert("最初らへん",2);
} catch(e){
document.write(br + br + e);
}
/*
Rubyとかいう言語にはこういうのがあるらしい。参考 : http://doc.ruby-lang.org/ja/1.9.2/class/Array.html
挿入先の配列数以上のindexが指定された場合は何もしないで元の配列を返すようにしたけど、
Rubyのやつの動作がどんなか知らん。破壊的メソッドなのかどうかも分からん。
今度お腹空いてないときに調べる。
複数要素の挿入に対応してなかったので直したつもりが、ぶっ壊れた。悲しい。
つーか、a はどうなってるべきなのか。今度お腹空いてないときに直す。
直った。非破壊メソッドにした。まだ何も調べてない。エラーメッセージが変。
第二引数以降に null も受け付ける感じにしてるけど、これでいいのか分からん。
まぁ使えるっちゃ使える。
*/
// grep
/* usage *//*
var gArray = 配列.grep(正規表現パターン);
*/
// test
var a = ["37573", "28471", 22222];
var r = /2/g;
alert( a.grep(r) + "/" + typeof a.grep(r) + "/" + (a.grep(r) instanceof Array) );
alert(a); //非破壊検査株式会社
/* memo(・´ω`・) *//*
Perlとかいう言語には、配列の中で条件に一致したものだけを返す grep とかいうのがあるらしいのでやってみた。
Array.filter依存。文字列以外は返さんようにしたけど、Perlのgrepがどんな動作か知らんので、何とも言えん感じ。
*/
// flatten
// 多次元配列を一次元配列に。
// usage
var a = [1, 2, 3, [4, 5, [6, 7, [8, 9], 10]]].flatten();
// check
document.write(a.length + " / "); //9
document.write(typeof a + " / "); //object
document.write((a instanceof Array) + " / " + "<br />"); //true
for (var i = 0, l = a.length; i < l; ++i) {
document.write(i + " : " + a[i] + "<br />");
}
/* memo *//*
javascripter さんの Array.reduce 依存のものを改変。エレガントだ。
Modify from : http://d.hatena.ne.jp/javascripter/20080520/1211231059
Sugar.js には、同様の動作で且つ落とす次元を指定出来る関数が入ってた。アレも作りたい。でも難しい。
その前にreduce非依存のやつを作りたいんだけど、上手くいってない。
reduceのと同じ理屈で、reduce抜きでもやれる筈なんだが。難しい…。
*/
// transpose
var a = [
[1, 2, 3],
[4, 5, 6]
];
//alert(a instanceof Array);//true
var at = a.transpose();
document.write(
at.length + "<br />" +
at.length + "<br />" +
at.length + "<br />" +
(at instanceof Array) + "<br />" +
typeof at + "<br />"
);
for (var k = 0, m = at.length; k < m; ++k) {
document.write(at[k] + "<br />");
}
/*正解*//*
1, 4
2, 5
3, 6
*/
/* memo(・´ω`・)*//*
関数内、最初のfor文で、配列の不揃いをチェックしている。
しかし、もっと効率的な方法がある筈だ。
*/
// uniq
var a = [];
a = [1, 2, 3, 4, 1, 2, 3, 4, 1, 1, 5, 6, 2, 3, 7, 8, 8, 8, 9];
document.body.innerHTML += a.uniq() + "<br />" + a + "<br />"; //動作及び非破壊チェック
a = [];
document.body.innerHTML += a[0] + " " + a.uniq()[0] + "<br />"; //空の配列の場合
/* answer *//*
1,2,3,4,5,6,7,8,9
1,2,3,4,1,2,3,4,1,1,5,6,2,3,7,8,8,8,9
undefined undefined
*/
/* memo *//*
jcf さんの uniq を改変。
https://gist.github.com/521923
indexof で重複チェックしてる。その手があったか。
自分はネストしたループで何とかしようとしてた。
内部的には同じ事なのかも知れないが、jcf's uniq の方がシンプルだし、分かりやすい。
オリジナルはループの中で毎回 i === 0 を見て、真だったら this[i] を push してたけど、
最初の要素は重複を気にしなくていいので、
ループより先に this[0] を push するようにして、この判定を省略してみた。
ちょっと速くなるはずだ。多分いける。
別の方法も考えてみる。今のところ、判定を every に差し替えるくらいしか思いつかん。
*/
// count
// http://docs.python.jp/2/library/array.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment