All the methods and the documentation are taken from lodash docs
Manipulating collections using functional and declerative code.
- No for-loops
- No while/do-while-loops
- No mutations
- Each lambda must be pure function by the Wikipedia definition
- Use only your standard library without any external libraries.
- You can use recursion even if there is only one function that needs that function.
- The result array must preserve the internal elements order of the input array.
- Do not break your pipeline.
- Do not copy-paste any code from Google. You are expected to understand which line of your code fully.
- Do not create any variable (primitive/object/function/class) inside your functions (function parameters are allowed).
- In case you worry about performance, use
collect
instead ofreduce
in case it solved your problem. - Accept array or list - it doesn't matter. (It is recommended to work with lists)
- Return array or list - it doesn't matter. (You can and sometimes should return
Stream
) - Do not use inner classes, anonymous classes or any other trick to avoid lambdas.
- Bonus: all your implementations must support parallel execution of streams.
- Only arrow functions and function pointers are allowed.
- If you are using Java and its the first time you write declarative code or you don't understand the rules, I recommend you to read: Functional Programming in Java 8 - Basic Concepts and Lambdas.
- If its the first time you manipulate collections, take the time to read about streams in your language.
- Don't skip over; the next one will be harder.
- If you are using Java, then I recommend you to read about the various
Collectors
methods.
- Javascript:
chunk(array, [size=1])
- Java:
<T> Stream<List<T>> chunk(List<T> list, int size)
Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.
array (Array)
: The array to process.[size=1] (number)
: The length of each chunk.
(Array)
: Returns the new array of chunks.
chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]
- Javascript:
concat(array, [values])
- Java:
<T> Stream<T> concat(List<T> list, T... args)
Creates a new array concatenating array with any additional arrays and/or values.
array (Array)
: The array to concatenate.[values] (...*)
: The values to concatenate.
(Array)
: Returns the new concatenated array.
var array = [1];
var other = concat(array, 2, [3], [[4]]);
console.log(other);
// => [1, 2, [3], [[4]]]
console.log(array);
// => [1]
- Javascript:
difference(array, [values])
- Java:
<T> Stream<T> difference(List<T> original, List<T>... lists)
Return an array of values not included in the other given arrays. The order and references of result values are determined by the first array.
array (Array)
: The array to inspect.[values] (...Array)
: The values to exclude.
(Array)
: Returns the new array of filtered values.
difference([2, 1], [2, 3]);
// => [1]
Javascript: intersection([arrays])
Java: <T> Stream<T> intersection(List<T> source, List<T>... lists)
Creates an array of unique values that are included in all given arrays. The order and references of result values are determined by the first array.
[arrays] (...Array)
: The arrays to inspect.
(Array)
: Returns the new array of intersecting values.
intersection([2, 1], [2, 3]);
// => [2]
- Javascript:
findLastIndex(array, [predicate=_.identity], [fromIndex=array.length-1])
- Java:
<T> OptionalInt findLastIndex(List<T> list, Predicate<T> predicate, int fromIndex)
Return the first index
i
from right to left such that both conditions fulfilled:
predicate(list.at(i)) == true
0 <= i <= fromIndex
.
array (Array)
: The array to inspect.[predicate=_.identity] (Function)
: The function invoked per iteration.[fromIndex=array.length-1] (number)
: The index to search from.
(number)
: Returns the index of the found element, else -1.
var users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
];
findLastIndex(users, function(o) { return o.user == 'pebbles'; });
// => 2
- Javascript:
dropRightWhile(array, [predicate=_.identity])
- Java:
<T> Stream<T> dropRightWhile(List<T> list, Predicate<T> predicate)
Creates a slice of array excluding elements dropped from the end. Elements are dropped until predicate returns false. The predicate is invoked with three arguments: (value, index, array).
array (Array)
: The array to query.[predicate=_.identity] (Function)
: The function invoked per iteration.
(Array)
: Returns the slice of array.
var users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
];
dropRightWhile(users, function(o) { return !o.active; });
// => objects for ['barney']
- Javascript:
flattenDeep(array)
- Java:
<T> Stream<T> flattenDeep(List<?> list)
// each element in the list is a list of list of... list ofT
. Elements in the given list may and sometimes will have different type. Look at the example.
Recursively flattens array.
array (Array)
: The array to flatten.
(Array)
: Returns the new flattened array.
flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
Note: To avoid reflection, implement this is Javascript only.
Javascript: flattenDepth(array, [depth=1])
Recursively flatten array up to depth times.
array (Array)
: The array to flatten.[depth=1] (number)
: The maximum recursion depth.
(Array)
: Returns the new flattened array.
var array = [1, [2, [3, [4]], 5]];
flattenDepth(array, 1);
// => [1, 2, [3, [4]], 5]
flattenDepth(array, 2);
// => [1, 2, 3, [4], 5]