让我们一起来起花名吧

原文:https://xcoder.in/2016/02/24/lets-hua/

起因

起因是我一个叫『小龙』的好基友由于某些原因离职去了一家跟阿里一样有着『花名文化』的公司,于是开始为花名犯愁。

结合之前妹纸『弍纾』在起花名的时候也遇到了同样的困扰,于是决定用 Node.js 写个『一本正经乱起花名』的程序。

准备

Chinese Random Name

首先起花名的原理就是胡乱随机一串字出来胡乱拼。

于是准备应该有 chinese-random-name,一个随机生成中文名的包。

使用它很简单,先把它 require 进来:

const randomName = require("chinese-random-name");

基本用法

如果你需要随机生成一个名字只需要 randomName.generate() 就可以了;如果你要随机一个姓那么就 randomName.surnames.getOne();如果你只需要获得名字,这里面就有点门道了。

高级用法

你可以随机生成一个名(不带姓的) randomName.names.get();你也可以指定名字的字数,一二三:

randomName.names.get1();
randomName.names.get2();
randomName.names.get3();

或者!

又或者!

然后或者!

你可以指定每个字的五行哦!

什么意思呢?比如你想给孩子起个名,然后孩子命里五行缺金,那么就可以:

randomName.names.get2("金金");

然后你就可能得到一个『紫铨』,两个字都是属金的。那么如果你孩子姓李,就叫李紫铨;如果孩子姓王,就叫王紫铨;如果姓爱新觉罗,那么就叫爱新觉罗·紫铨。

有木有想给我装得这个逼打个 82 分呢?剩下的就交给 666 吧。(ง •̀_•́)ง

Nomnom

这个包是用来解析命令行参数的。虽然市面上有挺多别的的,比如 commander 等,不过我还是最习惯 nomnom,用称手了就不想换了。

虽然它的 GitHub Repo 下面有这么一段话。

Nomnom is deprecated. Check out https://github.com/tj/commander.js, which should have most, if not all of the capability that nomnom had. Thank you!

不过再怎么说 nomnom 也是当年 substack 大神推荐的啊。(ಡωಡ)

Colorful

这个包是用来上色的。

毕竟五行是有颜色的哇。

const color = require("colorful");
console.log(color.red("(*/∇\*)"));

那么在你的终端就好看到一个红色的 (*/∇\*)

Is Chinese

用来判断是不是中文的包。

作为一个起名的命令行程序,你总得好好传参才行吧,总不能你随便传个咸鸭蛋🐣我也好好处理吧。

于是就用 is-chinese 来判断某个字符串是不是纯中文。

这个包是由前阿里小伙伴,CNode 站长唐少写的。

用起来也很简单,只要 isChinese("什么你要判断什么") 就可以了。

集合

$ npm install --save -d chinese-random-name
$ npm install --save -d nomnom
$ npm install --save -d colorful
$ npm install --save -d is-chinese

开工

其结果在这里

解析命令行参数

首先效果是这样的:

$ hua --help

Usage: hua [options]

Options:
-p PREFIX, --prefix PREFIX          to specify a prefix.
-s SUFFIX, --suffix SUFFIX          to specify a suffix.
-5 WUXING, --five-elements WUXING   the file elements (Wuxing) of huaming.
-c COUNT, --count COUNT             the count of huaming  [10]

使用者可以自己想一个前缀或者后缀,然后自定义(或者也可以不指定)两个字的五行,以及指定一次性生成多少个花名。

比如想要生成以 字为前缀的花名,就可以 $ hua --prefix 龙,得到结果可以是这样的:

 * 龙幼
 * 龙巡
 * 龙躬
 * 龙仇
 * 龙锤
 * 龙镒
 * 龙拾
 * 龙央
 * 龙些
 * 龙悠

如果想两个字分别所属金和谁,就可以 $ hua --five-elements 金水 来起花名:

 * 倩娥
 * 雀效
 * 黍棓
 * 姹溶
 * 馨沙
 * 宫闲
 * 裕混
 * 俗封
 * 绸娥
 * 瑞淦

想要得到这样一个命令行参数,我们可以用 nomnom 来解决。

var opts = require("nomnom")
    .script("hua")
    .option("prefix", {
        abbr: "p",
        help: "to specify a prefix.",
        metavar: "PREFIX"
    })
    .option("suffix", {
        abbr: "s",
        help: "to specify a suffix.",
        metavar: "SUFFIX"
    })
    .option("five-elements", {
        abbr: "5",
        help: "the file elements (Wuxing) of huaming.",
        metavar: "WUXING"
    })
    .option("count", {
        abbr: "c",
        help: "the count of huaming",
        metavar: "COUNT",
        default: 10
    })
    .parse();

上面的这段代码分别指定了脚本名为 hua,然后指定了 prefix / suffix / five-elementscount 四个参数,并把解析好的参数赋值给 opts 变量。

由于我希望这个包在通常的 Node.js 下都可以跑,所以没有用 let 之类的东西。

花名类

接下去要写一个花名类,这个类不只是可以在 CLI 之中使用,也可以让别人作为一个包来引入。然后实际上这个类就是要对 chinese-random-name 进行一个封装。

构造函数

var Hua = function(options) {
    this.options = options;

    // Do something...
};

首先这个 options 就是之前由 nomnom 解析出来的参数,当然有些参数是可选的。

接下去我们要在构造函数也就是 Hua 里面格式化前缀或者后缀(如果有的话),将他们弄成只有一个汉字的格式。

if(options.prefix) {
    options.prefix = options.prefix[0];
    if(!isChinese(options.prefix)) delete options.prefix;
}

if(options.suffix) {
    options.suffix = options.suffix[0];
    if(!isChinese(options.suffix)) delete options.suffix;
}

前后缀弄好之后要对五行进行分析了。

如果有前后缀那么忽略五行参数。

if(options.prefix && options.suffix) {
    delete options["file-elements"];
}

如果有前缀,那么忽略传进来的五行的第一个五行;如果有后缀那么忽略第二个字的五行。

var wuxing = "金木水火土";

.
.
.

} else if(options.prefix) {
    options["five-elements"] = options["five-elements"].substr(1, 1);
    if(-1 === wuxing.indexOf(options["five-elements"])) {
        delete options["five-elements"];
    }
} else if(options.suffix) {
    options["five-elements"] = options["five-elements"].substr(0, 1);
    if(-1 === wuxing.indexOf(options["five-elements"])) {
        delete options["five-elements"];
    }
}

如果前后缀都没有,那么要格式化一下该参数,使其仅剩两个有效的五行汉字。

} else {
    options["five-elements"] = options["five-elements"].substr(0, 2).split("");
    for(var i = 0; i < options["five-elements"].length; i++) {
        // 如果是无效五行或者冰没有这个字的话,随机一个五行出来
        if(-1 === wuxing.indexOf(options["five-elements"][i])) {
            options["five-elements"][i] = wuxing[Math.floor(Math.random() * 5)];
        }
    }

    // 字数不够,随机来凑
    while(options["five-elements"].length < 2) {
        options["five-elements"].push(wuxing[Math.floor(Math.random() * 5)]);
    }

    options["five-elements"] = options["five-elements"].join("");
}

以上的这些逻辑都写在构造函数里面,如果想要完整的构造函数可以看 huahua.js 文件。

生成一个花名

生成一个花名其实就是调用 randomName.names.get 系列函数们了。

  • 有前后缀:直接返回前缀加后缀。
  • 有前缀:返回前缀加 get1
  • 有后缀:返回 get1 加后缀。
  • 没有前后缀:直接返回 get2

注意:以上情况都会传进(哪怕是 undefined)五行参数。

所以 generateOne 函数长这样

Hua.prototype.generateOne = function() {
    if(this.options.prefix && this.options.suffix) {
        return this.options.prefix + this.options.suffix;
    }

    if(this.options.prefix) {
        debug(this.options["five-elements"]);
        return this.options.prefix + randomName.names.get1(this.options["five-elements"]);
    }

    if(this.options.suffix) {
        debug(this.options["five-elements"]);
        return randomName.names.get1(this.options["five-elements"]) + this.options.suffix;
    }

    return randomName.names.get2(this.options["five-elements"]);
};

生成 Count 个花名

还记得 CLI 的 count 参数么?因为为了方便,我们可以批量生成花名,所以就需要生成 Count 个花名的函数了。

实际上就是一个循环调用 generateOne 的函数而已。

Hua.prototype.generate = function(count) {
    if(!count) count = this.options.count || 10;

    var result = [];
    for(var i = 0; i < count; i++) {
        result.push(this.generateOne());
    }
    return result;
};

CLI 文件

刚刚那个 nomnom 解析就在这个文件里面,然后接下去就是实例化一个 Hua 对象,然后生成 count 个花名。

var hua = new Hua(opts);
var result = hua.generate();

最后把花名输出来就好了。

for(var i = 0; i < result.length; i++) {
    console.log(" * " + result[i]);
}

桥豆麻袋!

说好的五行颜色呢?!

好像是的哦,我们要在输出之前给 result 上个色儿。

遍历 result 里面的花名每个字,获取它的五行属性,然后涮上色儿。

chinese-random-name 暴露了字典中每个字的五行属性,只需要赋值一下就好了。

var dict = require("chinese-random-name").names.dict;

然后逐一对比。最后对应金木水火土的颜色值分别为:

var definedColors = [
    220, 83, 26, 197, 59
];

220 为黄色,代表金;83 为绿色,代表木;26 蓝色代表水;197 红色代表火;59 灰色代表土。

如果那个字无法找到属性,则不上色,保持默认。

result = result.map(function(name) {
    var withColor = "";

    for(var i = 0; i < 2; i++) {
        for(var j = 0; j < wuxing.length; j++) {
            var wx = wuxing[j];
            if(wx === " ") {
                withColor += name[i];
                break;
            }

            if(dict[wx].indexOf(name[i]) !== -1) {
                var color = new Color(name[i]);
                color.fgcolor = definedColors[j];
                withColor += color.toString();
                break;
            }
        }
    }

    return withColor;
});

至此我们的 CLI 就写好了,最后别忘了在 hua 这个 CLI 文件顶部加上一句话。

#!/usr/bin/env node

这代表到时候如果要 ./hua 的时候这个脚本是用 Node.js 来跑的。

收拾

本来想好好写篇起花名的牢骚,结果不知不觉写成了给初心者看的初级教程了,泪目 ( •̥́ ˍ •̀ू )

不嫌弃的就这么看看吧。

最后这里给出我写好的这个 hua 程序。

$ [sudo] npm install -g huaming

然后就能在命令行下面跑了,跑法上面几章有介绍过。它的 Repo 在这里

最后希望这个包在你们起花名的时候还真有那么一丢丢的用处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,748评论 6 342
  • 1、引言 数据库设计过程中表、字段等的命名规范也算是设计规范的一部分,不过设计规范更多的是为了确保数据库设计的合理...
    SnowflakeCloud阅读 40,950评论 0 48
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,145评论 9 118
  • 哈哈哈哈哈 人脸毁所有,请忽略不计 学以致用是我学习思维导图的目标 本周就依然按照此方法练习新概念课文背诵 感觉比...
    RubyWei1314阅读 1,045评论 0 0