4

I am currently seeking a way to "singularize" English words. I have found ways to do the opposite. Here's what I've come up with so far:

function singularize(word) {
  const endings = {
    ves: 'fe',
    ies: 'y',
    i: 'us',
    zes: '',
    ses: '',
    es: '',
    s: ''
  };
  return word.replace(
    new RegExp(`(${Object.keys(endings).join('|')})$`), 
    r => endings[r]
  );
}

However, this is not working in many cases (e.g. analysis – analyses, phenomenon – phenomena, series – series). Is there a more accurate way to do this without embedding a whole dictionary? Is there a way to access the dictionary of the browser?

And if there is no way without a dictionary, what would be at least a slightly more accurate solution?

Julius
  • 1,155
  • 9
  • 19
  • 4
    just use this library https://www.npmjs.com/package/pluralize – F.bernal Aug 09 '19 at 12:06
  • Yes use this https://github.com/blakeembrey/pluralize/blob/master/pluralize.js also you can integrate to web browser – Rishab Aug 09 '19 at 12:07
  • Also take a look at the [second answer](https://stackoverflow.com/a/27194360/8376184) on the question you linked! It has a singularize functionality as well (`word.plural(true)`) – FZs Aug 09 '19 at 12:40
  • May be you are looking for this [https://www.npmjs.com/package/pluralize](https://www.npmjs.com/package/pluralize). Using this package, you can convert a word in both direction. Besides you will be able to add singularize and pluralize rules too. – Shakibuz_Zaman Aug 09 '19 at 12:25

3 Answers3

3

I think everything in your code is great.

But a small error not in the code but instead it's in the object of endings you have.

This is the code after editing the endings object and with some test cases:

function singularize(word) {
    const endings = {
        ves: 'fe',
        ies: 'y',
        i: 'us',
        zes: 'ze',
        ses: 's',
        es: 'e',
        s: ''
    };
    return word.replace(
        new RegExp(`(${Object.keys(endings).join('|')})$`), 
        r => endings[r]
    );
}

console.log(singularize("papers"))
console.log(singularize("strategies"))
console.log(singularize("lives"))
console.log(singularize("games"))
console.log(singularize("cacti"))
console.log(singularize("dozes"))

But the functionality of your code is done.

1

another simple and easy way

const singularize = (word) => {
  if (word.endsWith("ses") || word.endsWith("xes") || word.endsWith("zes")) {
    return word.slice(0, -3);
  }
  if (word.endsWith("shes") || word.endsWith("ches")) {
    return word.slice(0, -4);
  }

  if (word.endsWith("ies")) {
    return word.slice(0, -3) + "y";
  }

  return word.slice(0, -1);
};
Ali Abbas
  • 1,415
  • 12
  • 19
0

Simple solution with customizable option

const stringPluralize = (count, str, suffix = 's', includeCount=true) => {
  let res = `${str}${count > 1 ? suffix : ''}`
  if(includeCount==true) return `${count} ${res}` 
  return res;
}


console.log( stringPluralize( 0, 'box', 'es') )
console.log( stringPluralize( 2, 'box', 'es') )

console.log( stringPluralize( 4, 'box', 'es', false) ) // 'false' for text only without counts

console.log( stringPluralize( 1, 'member', 's') )
console.log( stringPluralize( 11, 'member', 's') )
GMKHussain
  • 3,342
  • 1
  • 21
  • 19