Skip to content

Instantly share code, notes, and snippets.

@alucky0707
Created August 14, 2013 07:46
Show Gist options
  • Save alucky0707/6228798 to your computer and use it in GitHub Desktop.
Save alucky0707/6228798 to your computer and use it in GitHub Desktop.
JavaScriptでメソッドの補完をする。要harmony-reflect、--harmonyフラグ
(function () {
var
Proxy = require('harmony-reflect').Proxy;
//aとbの編集距離
function levenDist(a, b) {
var
i, j, x,
m = [[0]];
if (a === b) return 0;
if (a === '') return b.length;
if (b === '') return a.length;
for (j = 0; j <= b.length; j++) m[0][j] = j;
for (i = 1; i <= a.length; i++) {
m[i] = [i];
for (j = 1; j <= b.length; j++) {
m[i][j] = Math.min(
m[i - 1][j] + 1,
m[i][j - 1] + 1,
m[i - 1][j - 1] + (a.charAt(i - 1) === b.charAt(j - 1) ? 0 : 2));
}
}
return m[i - 1][j - 1];
}
//プロトタイプチェインをたどりながら、オブジェクトのプロパティ一覧を取得する
function getProps(obj) {
return obj === null ? [] : Object.getOwnPropertyNames(obj).concat(getProps(Object.getPrototypeOf(obj)));
}
//keyとvが似ているか評価(バイグラムなのかな?)
function rank(key, v) {
v = (v.match(/.{2}/g)||[v]).concat(v.slice(1).match(/.{2}/g)||[]);
return key.length === 1 ? (v.join('').match(new RegExp(key,'g'))||[]).length :
(key.match(/.{2}/g)||[key]).concat(key.slice(1).match(/.{2}/)||[]).reduce(function (m, k) {
return m + (v.indexOf(k) !== - 1);
}, 0);
}
//propsのなかから、keyに似たものを探す
function getKey(props, key) {
return props.map(function (k) {
return [k, levenDist(k, key)];
}).sort(function (a, b) {
return a[1] === b[1] ? rank(key, b[0]) - rank(key, a[0]) : a[1] - b[1] ;
})[0][0];
}
var
compProxy = {
get: function (obj, key) {
var
k, props = getProps(obj);
if (props.indexOf(key) !== -1) return obj[key];
k = getKey(props, key);
// console.log(key, k);
return obj[k];
}
};
function CompObj (obj) {
return Proxy(obj, compProxy);
}
module.exports = CompObj;
module.exports.levenDist = levenDist;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment