Skip to content

Instantly share code, notes, and snippets.

@think49
Last active July 19, 2017 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save think49/00326b750d48f5f9c48a042f1b19a1c2 to your computer and use it in GitHub Desktop.
Save think49/00326b750d48f5f9c48a042f1b19a1c2 to your computer and use it in GitHub Desktop.
multidimensional-map.js : 多次元Mapを生成

multidimensional-map.js

概要

多次元 Map を生成します。

使い方

[[[...keys], value], [[...keys], value], ...] からなる三次元配列を第一引数に指定する事で多次元構造の Map オブジェクトを返します。 new Map に渡す配列の内、key を配列で複数渡せる、と認識して頂ければOKです。

var map = createMultidimensionalMap([
          [[false, false], 'BB'],
          [[false, true], 'BA'],
          [[true, false], 'AB'],
          [[true, true], 'BB']
        ]);

console.log(map);
console.log(map.get(false).get(false)); // "BB"
console.log(map.get(false).get(true));  // "BA"
console.log(map.get(true).get(false));  // "AB"
console.log(map.get(true).get(true));   // "BB"

new Map を基準にしており、渡せるキー/値に制限はありません。NaN も同一判定できます。

var obj = {}, array = [],
    map = createMultidimensionalMap([
        [[obj, array, 'N'], 'OAN'],
        [['N', 'Y', true], 'NYT'],
        [[1, 'N', 'Y'], '1NY'],
        [[NaN, NaN, NaN], 'NaN']
      ]);

console.log(map);
console.log(map.get(obj).get(array).get('N')); // "OAN"
console.log(map.get('N').get('Y').get(true));  // "NYT"
console.log(map.get(1).get('N').get('Y'));     // "1NY"
console.log(map.get(NaN).get(NaN).get(NaN));   // "NaN"

参考リンク

/**
* multidimensional-map.js
*
* @version 1.0.0
* @author think49
* @url https://gist.github.com/think49/00326b750d48f5f9c48a042f1b19a1c2
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License)
*/
function createMultidimensionalMap (mapData) {
'use strict';
var rootMap;
{
var entry = mapData[0],
keys = entry[0],
keysIndex = keys.length - 1;
rootMap = new Map([[keys[keysIndex], entry[1]]]);
while (keysIndex--) {
rootMap = new Map([[keys[keysIndex], rootMap]]);
}
}
for (var i = 1, len = mapData.length, entry, keys, keysIndex, keysLen, map, newMap; i < len; ++i) {
entry = mapData[i];
keys = entry[0];
keysLen = keys.length;
if (keysLen > 1) {
map = rootMap;
for (var j = 0, key; j < keysLen; ++j) {
key = keys[j];
if (!map.has(key)) {
break;
} else {
map = map.get(key);
}
}
keysIndex = keys.length - 1;
newMap = j !== keysIndex ? new Map([[keys[keysIndex], entry[1]]]) : entry[1];
while (--keysIndex > j) {
newMap = new Map([[keys[keysIndex], newMap]]);
}
map.set(keys[j], newMap);
} else if (keysLen === 1) {
rootMap.set(keys[0], entry[1]);
}
}
return rootMap;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment