How to use random string as JSON object name - javascript

I am trying to create a JSON object, with a random string as the name, just like how Firebase does it.
Goal: replace child name with random string.
For example:
"Users" : {
"mGKgNDOw0qd77m6tmdDh76zOQOm2" : {
"email" : "someuser#gmail.com",
"firstName" : "some",
"lastName" : "user",
"username" : "someuser"
},
"vyMiCS7olNPh9bCXoKWqcIFNWVy2" : {
"email" : "someuser2#gmail.com",
"firstName" : "some",
"lastName" : "user2",
"username" : "someuser2"
}
}
This is what I got so far, I manage to get my head around with a string randomise function.
randomString(length) {
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
And I would like to push my data into the object with random string as the name.
I tried string interpolation but it does not work.
var expensesObject = {
uid: {
amount: spentAmount,
category: selectedCategory,
date: formattedDate,
time: formattedTime,
note: note
}
}

Consider this code
var users = {}
users[ randomString(20) ] = {
amount : spentAmount,
category : selectedCategory,
date : formattedDate,
time : formattedTime,
note : note
}

You can do this by setting directly the object's key using []:
var expensesObject = {}
expensesObject[uid] = {
amount: spentAmount,
category: selectedCategory,
date: formattedDate,
time: formattedTime,
note: note
}

You could use a single random number for a distinct place. The check if lower or upper case.
Then assign to the new key the property of uid and delete the property.
function replaceUID(object) {
object[random(28)] = object.uid;
delete object.uid;
}
function random(size) {
var r, s = '';
while (s.length < size) {
r = Math.floor(Math.random() * 62);
s += r >= 36 ? (r - 26).toString(36).toUpperCase() : r.toString(36);
}
return s;
}
var expensesObject = { uid: { amount: 'spentAmount', category: 'selectedCategory',
date: 'formattedDate', time: 'formattedTime', note: 'note' } };
replaceUID(expensesObject);
console.log(expensesObject);

Copy the object uid to a new object containing the random string
var expensesObject = {
uid: {
amount: 5,
category: "catA",
date: "02-03-2017",
time: "14:00:00",
note: "Notes"
}
};
var finalobject = {};
let propertyName = randomString(10); //get the random string
finalobject[propertyName] = expensesObject.uid; //copy uid object
console.log(finalobject);
function randomString(length) {
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}

You could do something like this:
function randomString(length) {
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
var keylength = 16; // <-- change as needed
var myObject = {
amount: spentAmount,
category: selectedCategory,
date: formattedDate,
time: formattedTime,
note: note
}
var expensesObject = {};
var uuid = randomString(keylength);
expensesObject[uuid]=myObject; // <-- use [ var_name ]

You also can create string and convert it to JSON object like this:
var expensesObjectStr = "{"+ '"'+ uid+'"'+": {"+
'"amount"'+":"+ spentAmount+","+
'"category"'+":"+'"'+ selectedCategory+'"'+","+
'"date"'+": "+'"'+ formattedDate+'"'+","+
'"time"'+": "+'"'+ formattedTime+'"'+","+
'"note"'+": "+'"'+ note+'"'+
"} }";
var obj = jQuery.parseJSON(expensesObjectStr);
Here small fiddle - https://jsfiddle.net/skyr9999/2dvffaty/

var temp = expensesObject[uid];
expensesObject[randomString(<length>)] = temp;

Related

Acces Array of object and accesing or checking ut

So i tried to make the program that formattting the input to be array and object, but i struggle to acces, check, and add an object to an array, here's the code, input and output
The program will ask for input from the user, the request will be formatted as:
{
name : (inputName),
location : (inputlocation),
request : [
{(productName ) : (totalRequest)}
e.g : {meatball : 1},
],
}
The program will check whether the same item has been previously ordered by the same user
If it is, then the totalRequest of the same item will be increased, if not, an object will be created with the format {productName : totalRequest }
let user = {
name : readLine.question("Name : "),
location : readLine.question('Location : '),
request : []
}
while(true){
var product = readLine.question('input your request : ').toLowerCase();
var total = readLine.question("total request : ");
var requestProduct = {}
//this is the part of the problem, the data is checked in here
for(let i of user.request){
for(let j in i){
if(j == product){
i[product] += total;
} else {
requestProduct[product] = total;
user.request.push(requestProduct);
}
}
}
var isEnough = readLine.question('Enough ?(yes/no)');
if(isEnough == 'yes'){
console.log(user);
break;
} else {
continue;
}
}
/**
* expected output :
* {
* name : Budi,
* Location : Supeno Street, number 150,
* request : [
* {meatball : 12},
* {"ice tea" : 12},
* ]
* }
* output on reality:
* {
* name : Budi,
* Location : Supeno Street, number 150,
* request : []
* }
* */
i've commented the problem part on the code review, i hope someone can help me solve the problem
You shouldn't loop through the object. Use Object.keys() to get the key of the object. Then you can check if this key matches what the user entered.
let found = false;
for (let i of user.request) {
let key = Object.keys(i)[0];
if (key == product) {
found = true;
i[key] += total;
break;
}
}
if (!found) {
user.request.push({[product]: total});
}

getting 'Cannot read property 'count' of undefined' in an if / else statement (Javascript)

i have an array appointment objects of which all each has this key: "RecurrenceRule". Either it is empty (null) or it has something of the following: "RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;"
This is how one element looks like:
{ appointmentId: 001239,
subject: "Something",
Client: "Bob",
StartTime: "2020-04-16T11:00:00.000Z",
EndTime: "2020-04-16T11:30:00.000Z",
km: 90,
RecurrenceRule: null,
},
What I want to do is iterate through appointments by the .reduce() function and if the current element has "RecurrenceRule": "FREQ=DAILY;INTERVAL=1;COUNT=5;", I want to take the value after 'COUNT=' and assign it to count and if RecurrenceRule is null, I want to assign 1 to count, if that makes sense. Below is the method:
export class AppointmentComponent implements OnInit {
appointments;
ngOnInit(){
this.getAppointments();
}
getAppointments(){
this.appointmentService.getAppointments().subscribe((data : any) => {
this.appointments= data.appointment;
this.groupByClient();
});
};
groupByClient(){
var result = [];
this.appointments.reduce(function (res, value) {
let diff = dayjs(value.EndTime).diff(dayjs(value.StartTime), "hour",true) % 60;
if(res[value.RecurrenceRule] !== null) {
let count = parseInt(value.RecurrenceRule.split("COUNT=")[1])
} else {
let count = 1;
}
if (!res[value.Client]) {
res[value.Client] = {
km: value.km,
Client: value.Client,
count: this.count,
difference: diff * this.count
};
result.push(res[value.Client]);
} else {
res[value.Client].km += value.km;
res[value.Client].difference += diff;
}
return res;
}, {});
}
}
However, when I run this I get the error message: ERROR TypeError: Cannot read property 'count' of undefined, pointing to the this.count lines. What is going wrong here? Is it to do with the nested this. ?
If you need more info please let me know.
When you declare a variable with let it is scoped to the block. In your case count doen't exist outside if(…) {…} else {…}
You should wirte
let count;
if(value.RecurrenceRule !== null) {
count = parseInt(value.RecurrenceRule.split("COUNT=")[1])
} else {
count = 1;
}
or
const count = value.RecurrenceRule ? parseInt(value.RecurrenceRule.split("COUNT=")[1]) : 1;
later in your code use count instead of this.count

Capture values in a code similar to JSON

I'm trying to make a tool for one game (Victoria II), the save game (the entire save game hasn't this format, only the part which i intend to use, the rest of save game hasn't any importance now) of Victoria II has this format:
AAA = {
B = {
random_text = 1000.00
another_one = 400.00
}
C= {
no_importance = 222
}
D = {
random_text = 5.00
another_one = 10.00
}
}
How the tool will work? The tool will calculate the GDP of the country AAA (there are 100 countries, firstly i want to calculate the GDP of AAA, but i will want to calculate of every one. The code of every country is three letters in uppercase), the B parameter is the domestic production of some goods (random_text and another_one), the C parameter has no importance, so, the tool will ignore it. The D parameter is the price of some goods (in this case, random_text and another_one, if not mistaken there are 20 goods). So, the tool (in JavaScript) must multiply the production of goods in the country with the price that each goods has, and then make a table with the GDP of every country. The question is: How i can do this with JavaScript? I'm trying to use regexp, but I'm always failing, the code captures the parameter C and makes the tool fails. For every country, i want to insert its name in the table and its respective GDP.
Note: In the link above, there are more comments about the working of the tool.
Assuming the format you show above is reliable, you could do a quick-and-dirty conversion to JSON via a few calls to .replace(), then parse that JSON and process the resulting object as required.
Not sure I understood what you were saying about the GDP calculation, but I think you mean that the GDP for AAA would be the sum of each B value multiplied by its corresponding D value, i.e., 1000.00 * 5.00 + 400.00 * 10.00 = 9000.
var input = ' /* your input here */ ';
var json = '{'
+ input.replace(/([^\s]+)\s*=/g,'"$1":')
.replace(/([^{\s])\n(\s*[^{}])/g,'$1,\n$2')
.replace(/,(\s*})/g,'$1')
+ '}';
var obj = JSON.parse(json);
var output = Object.keys(obj).map(function(v) {
return {
country: v,
gdp: Object.keys(obj[v].B).reduce(function(p, c) {
return p + obj[v].B[c] * obj[v].D[c];
}, 0)
};
});
After running the above, the output variable will be an array of objects with details in this format:
[ { "country": "AAA", "gdp": 9000 }, //etc. ]
Expand the following and run it to see it working with three countries:
var input = `AAA = {
B = {
random_text = 1000.00
another_one = 400.00
}
C= {
no_importance = 222
}
D = {
random_text = 5.00
another_one = 10.00
}
}
BBB = {
B = {
random_text = 111.00
another_one = 222.00
}
C= {
no_importance = 222
}
D = {
random_text = 3.00
another_one = 4.00
}
}
CCC = {
B = {
x = 10.0
y = 20.0
z = 30.0
}
C= {
no_importance = 222
}
D = {
x = 1.00
y = 2.00
z = 3.00
}
}`;
var json = '{'
+ input.replace(/([^\s]+)\s*=/g,'"$1":')
.replace(/([^{\s])\n(\s*[^{}])/g,'$1,\n$2')
.replace(/,(\s*})/g,'$1')
+ '}';
var obj = JSON.parse(json);
var output = Object.keys(obj).map(function(v) {
return {
country: v,
gdp: Object.keys(obj[v].B).reduce(function(p, c) {
return p + obj[v].B[c] * obj[v].D[c];
}, 0)
};
});
console.log(output);

Is it possible to pass object as parameter?

var obj = {
name1: 1,
name2: 2
}
function myF(obj) {
console.log(obj.name1) // by idea it must return 1
};
myF(obj)
Does anybody know how to pass object in function?
Yes objects make great parameters.
var p1 = {
name: "Tom",
age: 23,
isMale: true
};
var p2 = {
name: "Alicia",
age: 21,
isMale: false
};
var p3 = {
name: "Landon",
age: 1,
isMale: true
};
function greeting(person) {
var str = '';
str += 'Hello my name is ';
str += person.name + ' ';
str += 'I'm a ' + person.age + ' year old ';
if (person.isMale) {
str += age > 18 ? 'man' : 'boy';
} else {
str += age > 18 ? 'woman' : 'girl';
}
if (person.age < 3) {
str = 'Bah'
}
console.log(str);
};
greeting(p1); // 'Hello my name is Tom I'm a 23 year old man';
greeting(p2); // 'Hello my name is Alicia I'm a 21 year old woman;
greeting(p3); // 'Bah';
Objects are good for when you have a grouping of values that belong together and you don't want to pass them in individually (If they belong together they rarely should be passed on their own.)
This is very common practice. Many libraries will utilize a config object so one does not have to specify multiple params
Example:
function makeSquare(height, width, color, border)
Could be easier represented with
function makeSquare(config)
This would make it easier for users to leave out some parameters, say you wanted to makeSquare without a border you would not need to include the border param if you are passing and object.
With parameters
makeSquare(10, 20, red, null)
with Obj
config = {
height: 10,
width: 10,
color: 'red'
};
makeSquare(config);
If you had an extensive amount of configuration options you could see where this may save quite a bit of development time and space

JavaScript pluralize an english string

In PHP, I use Kuwamoto's class to pluralize nouns in my strings. I didn't find something as good as this script in javascript except for some plugins. So, it would be great to have a javascript function based on Kuwamoto's class.
http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/
Simple version (ES6):
const pluralize = (count, noun, suffix = 's') =>
`${count} ${noun}${count !== 1 ? suffix : ''}`;
Typescript:
const pluralize = (count: number, noun: string, suffix = 's') =>
`${count} ${noun}${count !== 1 ? suffix : ''}`;
Usage:
pluralize(0, 'turtle'); // 0 turtles
pluralize(1, 'turtle'); // 1 turtle
pluralize(2, 'turtle'); // 2 turtles
pluralize(3, 'fox', 'es'); // 3 foxes
This obviously doesn't support all english edge-cases, but it's suitable for most purposes
Use Pluralize
There's a great little library called Pluralize that's packaged in npm and bower.
This is what it looks like to use:
import Pluralize from 'pluralize';
Pluralize( 'Towel', 42 ); // "Towels"
Pluralize( 'Towel', 42, true ); // "42 Towels"
And you can get it here:
https://github.com/blakeembrey/pluralize
So, I answer my own question by sharing my translation in javascript of Kuwamoto's PHP class.
String.prototype.plural = function(revert){
var plural = {
'(quiz)$' : "$1zes",
'^(ox)$' : "$1en",
'([m|l])ouse$' : "$1ice",
'(matr|vert|ind)ix|ex$' : "$1ices",
'(x|ch|ss|sh)$' : "$1es",
'([^aeiouy]|qu)y$' : "$1ies",
'(hive)$' : "$1s",
'(?:([^f])fe|([lr])f)$' : "$1$2ves",
'(shea|lea|loa|thie)f$' : "$1ves",
'sis$' : "ses",
'([ti])um$' : "$1a",
'(tomat|potat|ech|her|vet)o$': "$1oes",
'(bu)s$' : "$1ses",
'(alias)$' : "$1es",
'(octop)us$' : "$1i",
'(ax|test)is$' : "$1es",
'(us)$' : "$1es",
'([^s]+)$' : "$1s"
};
var singular = {
'(quiz)zes$' : "$1",
'(matr)ices$' : "$1ix",
'(vert|ind)ices$' : "$1ex",
'^(ox)en$' : "$1",
'(alias)es$' : "$1",
'(octop|vir)i$' : "$1us",
'(cris|ax|test)es$' : "$1is",
'(shoe)s$' : "$1",
'(o)es$' : "$1",
'(bus)es$' : "$1",
'([m|l])ice$' : "$1ouse",
'(x|ch|ss|sh)es$' : "$1",
'(m)ovies$' : "$1ovie",
'(s)eries$' : "$1eries",
'([^aeiouy]|qu)ies$' : "$1y",
'([lr])ves$' : "$1f",
'(tive)s$' : "$1",
'(hive)s$' : "$1",
'(li|wi|kni)ves$' : "$1fe",
'(shea|loa|lea|thie)ves$': "$1f",
'(^analy)ses$' : "$1sis",
'((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",
'([ti])a$' : "$1um",
'(n)ews$' : "$1ews",
'(h|bl)ouses$' : "$1ouse",
'(corpse)s$' : "$1",
'(us)es$' : "$1",
's$' : ""
};
var irregular = {
'move' : 'moves',
'foot' : 'feet',
'goose' : 'geese',
'sex' : 'sexes',
'child' : 'children',
'man' : 'men',
'tooth' : 'teeth',
'person' : 'people'
};
var uncountable = [
'sheep',
'fish',
'deer',
'moose',
'series',
'species',
'money',
'rice',
'information',
'equipment'
];
// save some time in the case that singular and plural are the same
if(uncountable.indexOf(this.toLowerCase()) >= 0)
return this;
// check for irregular forms
for(word in irregular){
if(revert){
var pattern = new RegExp(irregular[word]+'$', 'i');
var replace = word;
} else{ var pattern = new RegExp(word+'$', 'i');
var replace = irregular[word];
}
if(pattern.test(this))
return this.replace(pattern, replace);
}
if(revert) var array = singular;
else var array = plural;
// check for matches using regular expressions
for(reg in array){
var pattern = new RegExp(reg, 'i');
if(pattern.test(this))
return this.replace(pattern, array[reg]);
}
return this;
}
Easy to use:
alert("page".plural()); // return plural form => pages
alert("mouse".plural()); // return plural form => mice
alert("women".plural(true)); // return singular form => woman
DEMO
Based on #pmrotule answer with some typescript magic and some additions to the uncountable array. I add here the plural and singular functions.
The plural version:
/**
* Returns the plural of an English word.
*
* #export
* #param {string} word
* #param {number} [amount]
* #returns {string}
*/
export function plural(word: string, amount?: number): string {
if (amount !== undefined && amount === 1) {
return word
}
const plural: { [key: string]: string } = {
'(quiz)$' : "$1zes",
'^(ox)$' : "$1en",
'([m|l])ouse$' : "$1ice",
'(matr|vert|ind)ix|ex$' : "$1ices",
'(x|ch|ss|sh)$' : "$1es",
'([^aeiouy]|qu)y$' : "$1ies",
'(hive)$' : "$1s",
'(?:([^f])fe|([lr])f)$' : "$1$2ves",
'(shea|lea|loa|thie)f$' : "$1ves",
'sis$' : "ses",
'([ti])um$' : "$1a",
'(tomat|potat|ech|her|vet)o$': "$1oes",
'(bu)s$' : "$1ses",
'(alias)$' : "$1es",
'(octop)us$' : "$1i",
'(ax|test)is$' : "$1es",
'(us)$' : "$1es",
'([^s]+)$' : "$1s"
}
const irregular: { [key: string]: string } = {
'move' : 'moves',
'foot' : 'feet',
'goose' : 'geese',
'sex' : 'sexes',
'child' : 'children',
'man' : 'men',
'tooth' : 'teeth',
'person' : 'people'
}
const uncountable: string[] = [
'sheep',
'fish',
'deer',
'moose',
'series',
'species',
'money',
'rice',
'information',
'equipment',
'bison',
'cod',
'offspring',
'pike',
'salmon',
'shrimp',
'swine',
'trout',
'aircraft',
'hovercraft',
'spacecraft',
'sugar',
'tuna',
'you',
'wood'
]
// save some time in the case that singular and plural are the same
if (uncountable.indexOf(word.toLowerCase()) >= 0) {
return word
}
// check for irregular forms
for (const w in irregular) {
const pattern = new RegExp(`${w}$`, 'i')
const replace = irregular[w]
if (pattern.test(word)) {
return word.replace(pattern, replace)
}
}
// check for matches using regular expressions
for (const reg in plural) {
const pattern = new RegExp(reg, 'i')
if (pattern.test(word)) {
return word.replace(pattern, plural[reg])
}
}
return word
}
And the singular version:
/**
* Returns the singular of an English word.
*
* #export
* #param {string} word
* #param {number} [amount]
* #returns {string}
*/
export function singular(word: string, amount?: number): string {
if (amount !== undefined && amount !== 1) {
return word
}
const singular: { [key: string]: string } = {
'(quiz)zes$' : "$1",
'(matr)ices$' : "$1ix",
'(vert|ind)ices$' : "$1ex",
'^(ox)en$' : "$1",
'(alias)es$' : "$1",
'(octop|vir)i$' : "$1us",
'(cris|ax|test)es$' : "$1is",
'(shoe)s$' : "$1",
'(o)es$' : "$1",
'(bus)es$' : "$1",
'([m|l])ice$' : "$1ouse",
'(x|ch|ss|sh)es$' : "$1",
'(m)ovies$' : "$1ovie",
'(s)eries$' : "$1eries",
'([^aeiouy]|qu)ies$' : "$1y",
'([lr])ves$' : "$1f",
'(tive)s$' : "$1",
'(hive)s$' : "$1",
'(li|wi|kni)ves$' : "$1fe",
'(shea|loa|lea|thie)ves$': "$1f",
'(^analy)ses$' : "$1sis",
'((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",
'([ti])a$' : "$1um",
'(n)ews$' : "$1ews",
'(h|bl)ouses$' : "$1ouse",
'(corpse)s$' : "$1",
'(us)es$' : "$1",
's$' : ""
}
const irregular: { [key: string]: string } = {
'move' : 'moves',
'foot' : 'feet',
'goose' : 'geese',
'sex' : 'sexes',
'child' : 'children',
'man' : 'men',
'tooth' : 'teeth',
'person' : 'people'
}
const uncountable: string[] = [
'sheep',
'fish',
'deer',
'moose',
'series',
'species',
'money',
'rice',
'information',
'equipment',
'bison',
'cod',
'offspring',
'pike',
'salmon',
'shrimp',
'swine',
'trout',
'aircraft',
'hovercraft',
'spacecraft',
'sugar',
'tuna',
'you',
'wood'
]
// save some time in the case that singular and plural are the same
if (uncountable.indexOf(word.toLowerCase()) >= 0) {
return word
}
// check for irregular forms
for (const w in irregular) {
const pattern = new RegExp(`${irregular[w]}$`, 'i')
const replace = w
if (pattern.test(word)) {
return word.replace(pattern, replace)
}
}
// check for matches using regular expressions
for (const reg in singular) {
const pattern = new RegExp(reg, 'i')
if (pattern.test(word)) {
return word.replace(pattern, singular[reg])
}
}
return word
}
The new intl API spec from ECMA will provide the plural rules function,
https://github.com/tc39/proposal-intl-plural-rules
Here's the polyfill that can be used today https://github.com/eemeli/IntlPluralRules
Taken from my blog: https://sergiotapia.me/pluralizing-strings-in-javascript-es6-b5d4d651d403
You can use the pluralize library for this.
NPM:
npm install pluralize --save
Yarn:
yarn add pluralize
Wherever you want to use the lib, you can require it easily.
var pluralize = require('pluralize')
I like to add it to the window object so I can just invoke pluralize() wherever I need it. Within my application.js root file:
window.pluralize = require('pluralize')
Then you can just use it anywhere, React components, or just plain Javascript:
<span className="pull-left">
{`${item.score} ${pluralize('point', item.score)}`}
</span>
console.log(pluralize('point', item.score))
I use this simple inline statement
const number = 2;
const string = `${number} trutle${number === 1 ? "" : "s"}`; //this one
console.log(string)
function pluralize( /* n, [ n2, n3, ... ] str */ ) {
var n = Array.prototype.slice.call( arguments ) ;
var str = n.pop(), iMax = n.length - 1, i = -1, j ;
str = str.replace( /\$\$|\$(\d+)/g,
function( m, p1 ) { return m == '$$' ? '$' : n[+p1-1] }
) ;
return str.replace( /[(](.*?)([+-])(\d*)(?:,([^,)]*))?(?:,([^)]*))?[)]/g,
function( match, one, sign, abs, not1, zero ) {
// if abs, use indicated element in the array of numbers
// instead of using the next element in sequence
abs ? ( j = +abs - 1 ) : ( i < iMax && i++, j = i ) ;
if ( zero != undefined && n[j] == 0 ) return zero ;
return ( n[j] != 1 ) == ( sign == '+' ) ? ( not1 || 's' ) : one ;
}
) ;
}
console.log( pluralize( 1, 'the cat(+) live(-) outside' ) ) ;
// the cat lives outside
console.log( pluralize( 2, 'the child(+,ren) (is+,are) inside' ) ) ;
// the children are inside
console.log( pluralize( 0, '$1 dog(+), ($1+,$1,no) dog(+), ($1+,$1,no) dog(+,,)' ) ) ;
// 0 dogs, no dogs, no dog
console.log( pluralize( 100, 1, '$1 penn(y+,ies) make(-1) $$$2' ) ) ;
// 100 pennies make $1
console.log( pluralize( 1, 0.01, '$1 penn(y+,ies) make(-1) $$$2' ) ) ;
// 1 penny makes $0.01
I’ve created a very simple library that can be used for words pluralization in JavaScript. It transparently uses CLDR database for multiple locales, so it supports almost any language you would like to use. It’s API is very minimalistic and integration is extremely simple. It’s called Numerous.
I’ve also written a small introduction article to it: «How to pluralize any word in different languages using JavaScript?».
Feel free to use it in your project. I will also be glad for your feedback on it.
To provide a simple and readable option (ES6):
export function pluralizeAndStringify(value, word, suffix = 's'){
if (value == 1){
return value + ' ' + word;
}
else {
return value + ' ' + word + suffix;
}
}
If you gave something like pluralizeAndStringify(5, 'dog') you'd get "5 dogs" as your output.
Using #sarink's answer, I made a function to create a string using key value pairs data and pluralizing the keys. Here's the snippet:
// Function to create a string from given key value pairs and pluralize keys
const stringPluralize = function(data){
var suffix = 's';
var str = '';
$.each(data, function(key, val){
if(str != ''){
str += val>0 ? ` and ${val} ${key}${val !== 1 ? suffix : ''}` : '';
}
else{
str = val>0 ? `${val} ${key}${val !== 1 ? suffix : ''}` : '';
}
});
return str;
}
var leftDays = '1';
var leftHours = '12';
var str = stringPluralize({day:leftDays, hour:leftHours});
console.log(str) // Gives 1 day and 12 hours
Use -ies or -s (depending on the second-to-last letter) if the word ends in a y, use -es if the word ends in a ‑s, -ss, -sh, -ch, -x, or -z, use a lookup table if the world is an irregular plural, and use -s otherwise.
var pluralize = (function () {
const vowels = "aeiou";
const irregulars = { "addendum": "addenda", "aircraft": "aircraft", "alumna": "alumnae", "alumnus": "alumni", "analysis": "analyses", "antenna": "antennae", "antithesis": "antitheses", "apex": "apices", "appendix": "appendices", "axis": "axes", "bacillus": "bacilli", "bacterium": "bacteria", "basis": "bases", "beau": "beaux", "bison": "bison", "bureau": "bureaux", "cactus": "cacti", "château": "châteaux", "child": "children", "codex": "codices", "concerto": "concerti", "corpus": "corpora", "crisis": "crises", "criterion": "criteria", "curriculum": "curricula", "datum": "data", "deer": "deer", "diagnosis": "diagnoses", "die": "dice", "dwarf": "dwarves", "ellipsis": "ellipses", "erratum": "errata", "faux pas": "faux pas", "fez": "fezzes", "fish": "fish", "focus": "foci", "foot": "feet", "formula": "formulae", "fungus": "fungi", "genus": "genera", "goose": "geese", "graffito": "graffiti", "grouse": "grouse", "half": "halves", "hoof": "hooves", "hypothesis": "hypotheses", "index": "indices", "larva": "larvae", "libretto": "libretti", "loaf": "loaves", "locus": "loci", "louse": "lice", "man": "men", "matrix": "matrices", "medium": "media", "memorandum": "memoranda", "minutia": "minutiae", "moose": "moose", "mouse": "mice", "nebula": "nebulae", "nucleus": "nuclei", "oasis": "oases", "offspring": "offspring", "opus": "opera", "ovum": "ova", "ox": "oxen", "parenthesis": "parentheses", "phenomenon": "phenomena", "phylum": "phyla", "quiz": "quizzes", "radius": "radii", "referendum": "referenda", "salmon": "salmon", "scarf": "scarves", "self": "selves", "series": "series", "sheep": "sheep", "shrimp": "shrimp", "species": "species", "stimulus": "stimuli", "stratum": "strata", "swine": "swine", "syllabus": "syllabi", "symposium": "symposia", "synopsis": "synopses", "tableau": "tableaux", "thesis": "theses", "thief": "thieves", "tooth": "teeth", "trout": "trout", "tuna": "tuna", "vertebra": "vertebrae", "vertex": "vertices", "vita": "vitae", "vortex": "vortices", "wharf": "wharves", "wife": "wives", "wolf": "wolves", "woman": "women", "guy": "guys", "buy": "buys", "person": "people" };
function pluralize(word) {
word = word.toLowerCase();
if (irregulars[word]) {
return irregulars[word];
}
if (word.length >= 2 && vowels.includes(word[word.length - 2])) {
return word + "s";
}
if (word.endsWith("s") || word.endsWith("sh") || word.endsWith("ch") || word.endsWith("x") || word.endsWith("z")) {
return word + "es";
}
if (word.endsWith("y")) {
return word.slice(0, -1) + "ies";
}
return word + "s";
}
return pluralize;
})();
////////////////////////////////////////
console.log(pluralize("dog"));
console.log(pluralize("cat"));
console.log(pluralize("fox"));
console.log(pluralize("dwarf"));
console.log(pluralize("guy"));
console.log(pluralize("play"));
Obviously, this can't support all English edge-cases, but it has the most common ones.
The concise version:
`${x} minute${x - 1 ? 's' : ''}`

Categories

Resources