我想比较一个人姓名的多种形式。考虑的等级是:
姓氏>名字>中间名,
完整拼写>初始,
全名(第一,中,最后)>部分名称(第一个,最后一个)
示例:
John<约翰肯尼迪< J. F. K.< J. F. Kennedy< John F. Kennedy< John Fitzgerald Kennedy
所以,如果我的人物对象可能是:
name_variant_1 = {
first: "John",
last: "Kennedy"
}
name_variant_2 = {
first: "J.",
mid: "F.",
last: "K."
}
将它们作为更好的名称进行比较的最佳方法是什么?
我想用最有效的措辞而不是很多分支逻辑来做到这一点。我宁愿不使用名称得分启发式。
谢谢!
答案 0 :(得分:0)
我想用最有效的措辞而不是很多分支逻辑来做到这一点。
嗯,基本上你需要分支逻辑,但有一些方法可以减少它的痛苦。有两个技巧:
if (a && !b) return 1; else if (!a && b) return -1; else return 0;
可简化为return a - b;
if (a != 0) return a; else return b;
可简化为return a || b;
所以你可以将比较逻辑表示为
function hasFullName(x) {
return ('first' in x) && ('mid' in x) && ('last' in x);
}
function isInitial(x) {
return x.charAt(x.length - 1) == ".";
}
function comparePart(a, b) {
return (!!a - !!b) // part exists at all?
|| (isInitial(b) - isInitial(a));
}
function compare(a, b) {
return (hasFullName(a) - hasFullName(b)) // full names always win
|| comparePart(a.last, b.last)
|| comparePart(a.first, b.first)
|| comparePart(a.mid, b.mid);
}
测试:
> [{"first":"J.","mid":"F.","last":"K."},{"first":"J.","mid":"F.","last":"Kennedy"},{"first":"John","mid":"F.","last":"Kennedy"},{"first":"John","mid":"Fitzgerald","last":"Kennedy"},{"first":"John"},{"first":"John","last":"Kennedy"}]
> .sort(compare)
[{"first":"John"},{"first":"John","last":"Kennedy"},{"first":"J.","mid":"F.","last":"K."},{"first":"J.","mid":"F.","last":"Kennedy"},{"first":"John","mid":"F.","last":"Kennedy"},{"first":"John","mid":"Fitzgerald","last":"Kennedy"}]