somali-names
Version:
Random Somali first names (male/female) with optional meanings. Library + CLI.
79 lines (69 loc) • 2.38 kB
JavaScript
const path = require("path");
const fs = require("fs");
const male = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "data", "male.json"), "utf8"));
const female = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "data", "female.json"), "utf8"));
/** Small PRNG for deterministic results when seed provided (Mulberry32) */
function makePRNG(seed) {
let t = seed >>> 0;
return function rand() {
t += 0x6D2B79F5;
let r = Math.imul(t ^ t >>> 15, 1 | t);
r ^= r + Math.imul(r ^ r >>> 7, 61 | r);
return ((r ^ r >>> 14) >>> 0) / 4294967296;
};
}
/**
* pick(array, rng?): one random element
*/
function pick(arr, rng = Math.random) {
const i = Math.floor(rng() * arr.length);
return arr[i];
}
/**
* randomName({ gender: 'male'|'female'|'any' = 'any', withMeaning=false, seed?: number })
*/
function randomName(opts = {}) {
const { gender = "any", withMeaning = false, seed } = opts;
const rng = seed === undefined ? Math.random : makePRNG(seed);
let pool = [];
if (gender === "male") pool = male;
else if (gender === "female") pool = female;
else pool = male.concat(female);
const n = pick(pool, rng);
return withMeaning ? n : n.name;
}
/**
* randomMany({ count=5, gender='any', unique=false, withMeaning=false, seed? })
*/
function randomMany(opts = {}) {
const { count = 5, gender = "any", unique = false, withMeaning = false, seed } = opts;
const rng = seed === undefined ? Math.random : makePRNG(seed);
let pool = [];
if (gender === "male") pool = male.slice();
else if (gender === "female") pool = female.slice();
else pool = male.concat(female);
const out = [];
const used = new Set();
for (let i = 0; i < count; i++) {
if (unique && used.size >= pool.length) break;
let item;
do { item = pick(pool, rng); } while (unique && used.has(item.name));
used.add(item.name);
out.push(withMeaning ? item : item.name);
}
return out;
}
/**
* findByPrefix(prefix, {gender='any'})
*/
function findByPrefix(prefix, opts = {}) {
if (!prefix) return [];
const { gender = "any" } = opts;
const pool = gender === "male" ? male : gender === "female" ? female : male.concat(female);
const s = prefix.toLowerCase();
return pool.filter(n => n.name.toLowerCase().startsWith(s)).map(n => n.name);
}
module.exports = {
male, female,
randomName, randomMany, findByPrefix
};