12

While writing a capitalize function is trivial, such that:

"hello" => "Hello" "hi there" => "Hi there"

How would one write it using point-free style using Ramda JS?

https://en.wikipedia.org/wiki/Tacit_programming

Tutan Ramen
  • 1,129
  • 1
  • 7
  • 23

5 Answers5

14

It would be something like that:

const capitalize = R.compose(
    R.join(''),
    R.juxt([R.compose(R.toUpper, R.head), R.tail])
);

Demo (in ramdajs.com REPL).

And minor modification to handle null values

const capitalize = R.compose(
    R.join(''),
    R.juxt([R.compose(R.toUpper, R.head), R.tail])
);

const capitalizeOrNull = R.ifElse(R.equals(null), R.identity, capitalize);
lorefnon
  • 12,112
  • 4
  • 54
  • 87
zerkms
  • 230,357
  • 57
  • 408
  • 498
  • As a follow-up question, how would you handle the null case when writing in a point-free style? If this function were called with capitalize(null) it will blow up. – Tutan Ramen Oct 13 '16 at 03:49
  • @TutanRamen prepend it with `ifElse(equals(null), identity, `, otherwise I think that's where `Maybe` monad would become useful. – zerkms Oct 13 '16 at 03:57
  • Awesome! Can even throw in `isNil` instead of `equals(null)` now! – tmikeschu Apr 19 '18 at 01:02
  • 3
    The `ifElse` + `identity` combo could be replaced with the arguably more readable `unless` function: `const capitalizeIfNotNil = R.unless(R.isNil, capitalize);` – Nicolás Fantone May 12 '18 at 01:08
13

You can partially apply replace with a Regex that runs toUpper on the first character:

const capitalize = R.replace(/^./, R.toUpper);

lax4mike
  • 4,535
  • 2
  • 16
  • 8
  • 3
    Ran some quick and dirty benchmarks on the answers provided, and yours is the fastest. – Christian Bankester Nov 30 '17 at 15:36
  • the 2nd param to `replace` is a string not a function though. Doesn't work for me – Damian Green Jun 04 '19 at 12:50
  • @DamianGreen Ramda implement `R.replace` with the native javascript string method. The 2nd argument can be a function too, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Syntax – lax4mike Jun 04 '19 at 18:42
6

I suggest using R.lens:

const char0 = R.lens(R.head, R.useWith(R.concat, [R.identity, R.tail]));

R.over(char0, R.toUpper, 'ramda');
// => 'Ramda'
davidchambers
  • 20,922
  • 14
  • 68
  • 95
4

I put together some quick and dirty benchmarks for anyone interested. Looks like @lax4mike's is fastest of the provided answers (though the simpler, non-point-free str[0].toUpperCase() + str.slice(1) is way faster [and also not what OP was asking for, so that's moot]).

https://jsfiddle.net/960q1e31/ (You'll need to open the console and run the fiddle to see the results)

Christian Bankester
  • 1,624
  • 2
  • 13
  • 18
1

For anyone reaching this looking for a solution that capitalizes the first letter and also lowercases the rest of the letters, here it is:

const capitalize = R.compose(R.toUpper, R.head);
const lowercaseTail = R.compose(R.toLower, R.tail);
const toTitle = R.converge(R.concat, [capitalize, lowercaseTail]);

toTitle('rAmdA');
// -> 'Ramda'
Nicolás Fantone
  • 1,589
  • 15
  • 24