どんなに多次元の配列でもディープコピー(値渡し)する
/**
* @return {[type]} [description]
*/
Array.prototype.clone = function() {
return JSON.parse(JSON.stringify(this));
};
.map
の多次元版
/**
* INFO: 3次元以降に対応していない。したい。
* @param {[type]}
* @return {[type]}
*/
Array.prototype.mapAll = function(fn) {
return this.map((a, y)=> {
return a.map((v, x)=> {
return fn(v, { x:x, y:y }, this);
});
});
};
右回転する
/**
* 右回転する
* INFO: 3次元以降に対応していない。したい。
* @return {[type]} [description]
*/
Array.prototype.turn = function() {
return this.mapAll((_, p, a)=> this[this.length-1-p.x][p.y]);
};
条件にあてはまる要素のkeyを配列にして返す
// 例
var a = [ { number: 10 }, { number: 20 }, { number: 20 }, { number: 30 } ];
var b = a.reduce(function( prev, curr, index, array ) {
if ( curr.number === 20 ) {
prev.push( index );
}
return prev;
}, [] );
console.log(b);
JSON.parse
can parse 'false'
, '1'
to false
, 1
as well.
/**
* @return {any} - "getAttribute" is return null when not found the attribute.
*/
getValueByAttr(attributeName) {
var v = document.querySelector('[data-aja-meta-search]').getAttribute(attributeName);
// INFO: parse `'false'`, `'1'` to `false`, `1` as well.
return JSON.parse(v);
}
2つの配列をマージする
- コンフリクト起きた要素はcallbackが発火される
- callbackを使ってどちらの値を使うかなど選択できる
/**
* 非破壊型
* sample: `[0,1].merge(1, [0,0]) => [0,0,0]`
* @param {[type]} X - 位置をindexで指定
* @param {[type]} arr - マージしたい配列
* @param {Function} fn - call when conflict.
* @return {[type]} [description]
*
* INFO: .map関数でやりたかったが値が特殊値`empty`の場合はmapのコールバックが呼ばれないorz
*/
Array.prototype.merge = function(X, arr, fn = function(val1, val2) { return val2 }) {
var newArr = [];
var newArrLength = Math.max(X + arr.length, this.length);
for (var i = 0; i < newArrLength; i++) {
var val = this[i];
if(i<X) {
newArr[i] = val;
}
else if(undefined !== this[i] && undefined !== arr[i-X]) {
newArr[i] = fn(val, arr[i-X], i);
}
else {
newArr[i] = undefined !== arr[i-X] ? arr[i-X] : this[i];
}
}
return newArr;
};
縦軸と横軸入れ替える
/**
* 縦軸と横軸入れ替える
* `左上と右下を結ぶ`軸で入れ替えるのであらゆる面で都合が良い
* @return {[type]}
*/
Array.prototype.transpose = function() {
return this[0].map((_, i)=> this.map(a=> a[i]));
}
consoleに視認性良く表示させる
/**
* 2次元配列専用
* @return {[type]}
*/
Array.prototype.stringify = function() {
var str = '\n';
this.forEach((arr)=> {
str += JSON.stringify(arr) + "\n";
});
return str;
};
条件(fn)にあった場所を{x, y}
の配列で返す
/**
* INFO: 3次元以降に対応していない。したい。
* @param {function}
* @arg {any} - {探索中の値}
* @arg {object} - {x,y}
* @return {Array}
*/
Array.prototype.getPositions = function(fn) {
return this.map((a, y)=> {
return a.map((v, x)=> {
return fn(this[y][x], { x:x, y:y }) ? { x:x, y:y } : undefined;
}).filter((v)=> v!==undefined);
})
// INFO: 2次元配列を1次元配列に
.reduce((pre,current) => {pre.push(...current);return pre},[]);
};
// 以下も同じ
Array.prototype.getPositions = function(fn) {
return this.reduce((prev1,curr1,y,a)=> {
return a.reduce((prev2,curr2,x)=> {
if (fn(this[y][x], { x:x, y:y })) {
prev1.push({ x:x, y:y });
}
return prev1;
}, []);
}, []);
};
他にも
# INFO: [4,3,4,5,4,3,2,2,4,5,3,3,3,3,5,5,3,4,4] といった配列を出現順に並び替える
# INFO: 以下では v.id となっているが これは 値が { id: 3, aId, 2, bId: 8 } のときに id で比較させているため。値が 3 であれば v だけで良い
sortByFrequency = (array) ->
frequency = {}
array.forEach (v) ->
frequency[v.id] = 0
uniques = array.filter((v) ->
++frequency[v.id] == 1
)
uniques.sort (a, b) ->
frequency[b.id] - frequency[a.id]
Array.prototype.removeDuplicates = ()->
Array.from(new Set(this))
Array.prototype.serialize = ()->
this.reduce((pre,current)->
pre.push.apply(pre, current);
pre
,[])
恒久的なカウントアップ
const countUp = function(key) {
const a = [];
a[key] = JSON.parse(localStorage.getItem(key));
a[key] === null && a[key] = 0;
localStorage.setItem(key, JSON.stringify(++a[key]));
return a[key];
};