Unashamedly monkey patching JavaScript to be more like Ruby.
Ruby (and Rails) has loads of really nice methods, now you can use them in JS as well!
Ruby Monkey helps to make your JavaScript code more code elegant, fun and productive!
Now you can write JS code like this:
[1,2,3].last // 3
[1,2,3].count // 3
(21).ordinalize // "21st"
"RubyMonkey".downcase.reverse // "yeknomybur"
[1,2,3].sum.squared // 36
["A","A","C","A","B","A","B"].tally // {"A": 4, "C": 1, "B": 2}
(1).day.ago // yesterdaynpm install rubydooThen just add either require "rubydoo" or import "rubydoo" to the top of any JS file and suddenly coding in JS becomes a lot more fun and productive!
In general, if you know the Ruby methods you should be able to use them in almost the same way, with a few slight changes:
- Blocks change to arrow functions
- JavaScript does not support appending symbols to the end of function names, so Boolean methods can't end in a
?, so these haveisprepended to them.
So for example, this Ruby:
[1,2,3].count{ |n| n.odd? }Would be written in JavaScript as:
[1,2,3].count( n => n.isOdd )Ruby has this really nice syntax to make calling methods on objects easier, so instead of [1,2,3].map { |n| n.next } you can just write [1,2,3].map(&:next)
JavaScript doesn't let you use & and doesn't have symbol literals, but you can use $ and it does have template literals and tag functions, so in Ruby Doo, you can do the same thing like this:
[1,2,3].map($`next`)Checks if the number is even.
(4).even; // true
(5).even; // falseChecks if the number is odd.
(3).odd; // true
(10).odd; // falseConverts the number to a string.
(42).to_s; // "42"Returns the next integer.
(10).next; // 11Rounds the number to the nearest integer.
(4.7).round; // 5
(4.2).round; // 4Returns the smallest integer greater than or equal to the number.
(4.2).ceil; // 5Returns the largest integer less than or equal to the number.
(4.9).floor; // 4Returns an array of the digits of the number.
(123).digits; // [1, 2, 3]Returns an array of all factors of the number.
(12).factors; // [1, 2, 3, 4, 6, 12]Checks if the number is prime.
(7).prime; // true
(9).prime; // falseChecks if the number is an integer.
(10.5).integer; // false
(10).integer; // trueChecks if the number is positive.
(5).positive; // true
(-3).positive; // falseChecks if the number is negative.
(-10).negative; // true
(5).negative; // falseChecks if the number is zero.
(0).zero; // true
(1).zero; // falseReturns the square of the number.
(4).squared; // 16Returns the cube of the number.
(3).cubed; // 27Returns the ordinal suffix of the number.
(1).ordinal; // "st"
(2).ordinal; // "nd"
(3).ordinal; // "rd"
(4).ordinal; // "th"
(11).ordinal; // "th"Returns the number as an ordinal string.
(1).ordinalize; // "1st"
(2).ordinalize; // "2nd"
(3).ordinalize; // "3rd"
(4).ordinalize; // "4th"
(11).ordinalize; // "11th"Iterates from the current number up to n, calling func if provided.
(3).upto(6, console.log);
// Logs: 3, 4, 5, 6
(3).upto(6);
// Returns: [3, 4, 5, 6]Executes func the given number of times, passing the index as an optional argument.
(3).times(_ => console.log("Ruby!"));
// Logs: Ruby!Ruby!Ruby!
(3).times(i => console.log(`Iteration: ${i}`));
// Logs: Iteration: 0, Iteration: 1, Iteration: 2Returns the remainder of the number divided by n.
(10).mod(3); // 1Returns an array containing the quotient and remainder of division by n.
(10).divmod(3); // [3, 1]Computes the greatest common divisor (GCD) of the number and n.
(48).gcd(18); // 6Computes the least common multiple (LCM) of the number and n.
(4).lcm(6); // 12Checks if the number is between a and b (inclusive).
(5).between(1, 10); // true
(15).between(1, 10); // falseReturns the string reversed.
"hello".reverse; // "olleh"Returns the length of the string.
"hello".size; // 5Converts the string to an integer, returning 0 if conversion fails.
"123".to_i; // 123
"abc".to_i; // 0Converts the string to a float, returning 0 if conversion fails.
"12.34".to_f; // 12.34
"abc".to_f; // 0Returns the string in lowercase.
"Hello".downcase; // "hello"Returns the string in uppercase.
"hello".upcase; // "HELLO"Capitalizes only the first character of the string.
"hello world".upcase_first; // "Hello world"Lowercases only the first character of the string.
"Hello World".downcase_first; // "hello World"
Removes leading, trailing, and multiple consecutive spaces.
" Hello world ".squish; // "Hello world"Checks if the string is empty or contains only whitespace.
" ".blank; // true
"hello".blank; // falseChecks if the string is completely empty (not even whitespace).
"".empty; // true
" ".empty; // falseRemoves _id from the end (if present) and replaces underscores with spaces, capitalizing the first letter.
"user_name".humanize; // "User name"
"post_id".humanize; // "Post"Capitalizes each word in the string.
"hello world".titleize; // "Hello World"Converts the string into a URL-friendly format (lowercase, hyphenated).
"Hello, World!".parameterize; // "hello-world"Returns an array of individual characters.
"hello".chars; // ["h", "e", "l", "l", "o"]Returns the number of times substring appears in the string.
"hello world".count("l"); // 3Checks if the string starts with the given substring.
"hello world".starts_with("hello"); // trueChecks if the string ends with the given substring.
"hello world".ends_with("world"); // trueReturns the first n characters of the string. If n is omitted, returns the first character.
"hello".first(2); // "he"
"hello".first(); // "h"Returns the last n characters of the string. If n is omitted, returns the last character.
"hello".last(2); // "lo"
"hello".last(); // "o"Returns the first element of the array.
[1, 2, 3].first; // 1
[].first; // undefinedReturns the second, third, fourth, or fifth element of the array.
[10, 20, 30].second; // 20
[10].third; // undefinedReturns the 42nd element (index 41) of the array.
Array(50).fill(0).map((_, i) => i + 1).forty_two; // 42### array.third_to_last, array.second_to_last, array.last
Returns the third-to-last, second-to-last, or last element of the array.
[1, 2, 3, 4].second_to_last; // 3
[].last; // undefinedReturns true if the array is empty, false otherwise.
[].empty; // true
[1].empty; // falseClears all elements from the array.
let arr = [1, 2, 3];
arr.clear;
console.log(arr); // []Returns the length of the array.
[1, 2, 3].size; // 3Returns the smallest or largest number in the array.
[5, 3, 9].min; // 3
[5, 3, 9].max; // 9
[].min; // undefinedReturns a new array with duplicate elements removed.
[1, 2, 2, 3].uniq; // [1, 2, 3]Converts the array into a human-readable sentence.
["a", "b", "c"].to_sentence; // "a, b and c"Returns a new array with null and undefined values removed.
[1, null, 2, undefined, 3].compact; // [1, 2, 3]Converts the array into a string joined by /.
["users", 42, "edit"].to_param; // "users/42/edit"Returns true if at least one element satisfies func, or if the array is not empty.
[1, 2, 3].any(x => x > 2); // true
[].any(); // falseReturns true if exactly one element satisfies func.
[1, 2, 3].one(x => x > 2); // true
[1, 2, 3, 4].one(x => x > 2); // falseReturns the sum of all elements, or applies func before summing.
[1, 2, 3].sum; // 6Returns a new array without elements matching func.
[1, 2, 3, 4].reject(x => x % 2 === 0); // [1, 3]
Splits the array into two: one matching func, one not.
[1, 2, 3, 4].partition(x => x % 2 === 0); // [[2, 4], [1, 3]]Returns the number of elements satisfying func, or the total length.
[1, 2, 3, 4].count(x => x % 2 === 0); // 2
[1, 2, 3].count(); // 3Extracts values of the given property from an array of objects.
[{id: 1}, {id: 2}].pluck("id"); // [1, 2]Returns a new array starting from index n.
[10, 20, 30, 40].from(2); // [30, 40]
### `array.product(arr)`
Returns all possible combinations of elements from both arrays.
```javascript
[1, 2, 3].product([4,5]); // [[1,4], [1,5], [2,4],[2,5], [3,4], [3,5]]Returns all possible combinations of n elements.
[1, 2, 3].combination(2); // [[1,2], [1,3], [2,3]]Counts occurrences of each unique element.
["a", "b", "a"].tally(); // { a: 2, b: 1 }Returns overlapping subarrays of size n.
[1, 2, 3, 4].each_cons(2); // [[1,2], [2,3], [3,4]]Returns a rotated array by n places.
[1, 2, 3].rotate(); // [2, 3, 1]Returns n random elements.
[1, 2, 3, 4].sample(2); // Random subsetZips two arrays together.
[1, 2, 3].zip(["a", "b", "c"]); // [[1, "a"], [2, "b"], [3, "c"]]Returns a merged array without duplicates.
[1, 2].union([2, 3], [3, 4]); // [1, 2, 3, 4]collect → map
all → every
select → filter
each → forEach
detect → find
inject → reduce
delete_if → reject
Checks if an object has no keys.
({}).empty; // true
({ a: 1 }).empty; // falseReturns the number of keys in the object.
({ a: 1, b: 2 }).size; // 2`
Returns an array of the object's values.
({ a: 1, b: 2 }).values; // [1, 2]Returns an array of the object's keys.
({ a: 1, b: 2 }).keys; // ["a", "b"]Returns an array of [key, value] pairs.
({ a: 1, b: 2 }).entries; // [["a", 1], ["b", 2]]Removes all properties from an object (mutates it).
const obj = { a: 1, b: 2 }; obj.clear console.log(obj); // {}
Returns a new object with null and undefined values removed.
({ a: 1, b: null, c: undefined }).compact; // { a: 1 }Returns a new object with key-value pairs where func(key, value) is true.
({ a: 1, b: 2 }).select(([k, v]) => v > 1); // { b: 2 }Alias for select.
Returns a new object with key-value pairs where func(key, value) is false.
({ a: 1, b: 2 }).reject(([k, v]) => v > 1); // { a: 1 }Alias for reject.
Checks if an object has a given key.
({ a: 1 }).has_key("a"); // true
({ a: 1 }).has_key("b"); // falseChecks if an object contains a given value.
({ a: 1, b: 2 }).has_value(2); // true
({ a: 1 }).has_value(3); // falseReturns the first key where the value matches, or undefined if not found.
({ a: 1, b: 2 }).key(2); // "b"
({ a: 1 }).key(3); // undefinedIf func is provided, checks if any key-value pair matches func(key, value). If func is omitted, returns true if the object is not empty.
({ a: 1, b: 2 }).any(); // true
({}).any(); // false
({ a: 1, b: 2 }).any(([k, v]) => v > 1); // trueReturns a new object excluding specified keys.
({ a: 1, b: 2, c: 3 }).except("b", "c"); // { a: 1 }