如何表达这种逻辑?

时间:2015-03-29 19:37:23

标签: javascript

我想比较一个人姓名的多种形式。考虑的等级是:

姓氏>名字>中间名,

完整拼写>初始,

全名(第一,中,最后)>部分名称(第一个,最后一个)

示例:

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."
}

将它们作为更好的名称进行比较的最佳方法是什么?

我想用最有效的措辞而不是很多分支逻辑来做到这一点。我宁愿不使用名称得分启发式。

谢谢!

1 个答案:

答案 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"}]