Categories
Lodash

Learn JavaScript by Implementing Lodash Methods: Unique Array Entries

In this article, we’ll look at and learn more about JavaScript by implementing some Lodash methods in plain JavaScript, including uniq uniqBy , and uniqWith.


‘uniq’

The Lodash uniq method creates an array without duplicate values. Only the first occurrence of each value appears in the returned array.

Since JavaScript already has the set data structure, we can use that with the spread operator to remove all the duplicates from the original array and return it.

We can implement this as follows:

const uniq = arr => [...new Set(arr)]

In the code above, we just converted arr to a set to remove duplicate values and then converted it back to an array with the spread operator.

Then when we call it as follows …

const result = uniq([1, 2, 2, 3]);

… we get that result is [1, 2 ,3] .


'uniqBy'

uniqBy is like uniq except it takes an iteratee function, which is run before comparing the values for uniqueness. This means we can’t just convert it to a set. Instead, we have to run iteratee and then compare them to the existing entries in the array we return.

To do that, we implement the uniqBy in the following way:

const uniqBy = (arr, iteratee) => {
  let uniques = [];
  for (let a of arr) {
    const mappedUniques = uniques.map(iteratee);
    if (!mappedUniques.includes(iteratee(a))) {
      uniques.push(a);
    }
  }
  return uniques;
}

In the code above, we have the uniques array, which will have the array of unique entries that we’ll return.

Then we loop through arr with the for...of loop. Inside the loop, we map the uniques array with iteratee to get the mapped values.

Next, we check if each array entry is already in uniques by checking if it’s in the mappedUniques array instead of uniques since we want to compare the uniqueness after it’s been converted by the iteratee function.

If it’s not included by checking with the includes method, then we push the value into uniques.

Once the loop is finished, we return uniques. Then when we call it as follows:

const result = uniqBy([1, 2, 2.1, 3], Math.floor);

Then result is [1, 2, 3] since 2 and 2.1 are the same after calling Math.floor on them. iteratee can be any function that takes one argument and returns something derived from it.


'uniqWith'

uniqWith is like uniq except it accepts a comparator that’s run to compare the existing values that have unique values with the ones that doesn’t.

If the entry in the original array isn’t in the array with unique values, then we put it into the array with the unique values.

The array with unique values is returned in the end after checking all the values in the given array.

We can implement it as follows:

const uniqWith = (arr, comparator) => {
  let uniques = [];
  for (let a of arr) {
    if (uniques.findIndex(u => comparator(a, u)) === -1) {
      uniques.push(a);
    }
  }
  return uniques;
}

In the code above, we have:

uniques.findIndex(u => comparator(a, u)) === -1

This checks to see if the items in uniques are the same as the array entry that we’re looping through. If it isn’t (as indicated by the return value -1), then we put it in uniques.

When the loop is done, we return uniques.

Then we run it as follows:

const result = uniqWith([1, 2, 2.1, 3], (a, b) => Math.floor(a) === Math.floor(b));

From this, we get [1, 2, 3] as the value of result since our comparator determines that if the floor of both values is the same, then they’re the same. The comparator function has to take two arguments with the two values to compare.


Conclusion

The uniq Lodash method can easily be implemented with plain JavaScript sets and the spread operator

uniqBy is a bit harder to implement since we need to map the values with the iteratee function that’s passed in before we can compare them for uniqueness.

uniqWith is similar to uniqBy in that we have to run the comparator function to compare the values to determine if the items are unique.

Categories
Lodash

Plain JavaScript Versions of Lodash Methods to Reverse and Sort Arrays

Lodash is a very useful utility library that lets us work with objects and arrays easily.

However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.

In this article, we’ll look at how to replace the reverse , slice , tail, takrRight, takeRightWhile and take methods with plain JavaScript code.

reverse

The Lodash reverse method reverses an array so that the first element becomes the last 2nd becomes 2nd last and so on.

This method is based on Arrar.prototype.reverse so that we don’t need to use Lodash’s reverse to reverse arrays.

We can just implement Lodash’s reverse method as follows:

const reverse = arr => arr.reverse()

Then we can call it as follows:

const result = reverse([1, 2, 3]);

and we get that result is [3, 2, 1] .

slice

Lodash’s slice method returns a slice of an array from the beginning index up to the end index. We can specify the start and end index.

It’s based on Array.prototype.slice so we don’t need to use it. If we really want Lodash’s slice method, we can implement it as follows:

const slice = (arr, start, end) => arr.slice(start, end)

We just called the arr ‘s slice method with the start and end index.

We can call it as follows:

const result = slice([1, 2, 3], 1, 2);

and we get that result is [2] .

tail

The tail method returns an array that has all but the first element of the array.

We can implement it as follows:

const tail = (arr) => arr.slice(1)

In the code above, we just called slice with 1 to exclude the first element

We can call it as follows:

const result = tail([30, 40, 50]);

Then result is [40, 50] .

take

take returns a slice of an array with n elements are taken from the beginning

Again, we can implement with slice as follows:

const take = (arr, n) => arr.slice(n)

Passing n as the first argument of slice returns an array with the first n entries removed.

We can call it as follows:

const result = take([30, 40, 50], 2);

Then we get that result is [50].

takeRight

The takeRight method returns a slice of an array with the n elements removed from the end.

Once again, we can use slice as follows:

const takeRight = (arr, n) => arr.slice(0, -n)

In the code above, we passed in 0 and -n to slice so that we return an array with from the first to the nth last entry inside.

Then when we call it as follows:

const result = takeRight([30, 40, 50], 2);

we get that result is [30] .

takeRightWhile

takeRightWhile returns a new array with the entries taken from the original array from the right until the given predicate that we used to end the method by returning the array returns true .

We can implement it as follows:

const takeRightWhile = (arr, predicate) => {
  let takenArr = [];
  for (let i = arr.length - 1; i >= 0; i--) {
    if (!predicate(arr[i])) {
      takenArr.push(arr[i]);
    } else {
      return takenArr.reverse();
    }
  }
  return takenArr.reverse();
}

In the code above, we looped through arr in reverse with a for loop. Then we run the predicate function in each iteration with each element as the argument and see if it returns true .

If it doesn’t then we push the entry into takenArr . Otherwise, we return takenArr reversed so that we have the elements in the original order.

Then we can call it as follows:

const result = takeRightWhile([30, 40, 50], a => a < 40);

and result is [40, 50] since we specifies that we stop if the first entry called with the predicate returns true .

Conclusion

The takeRightWhile method can easily be implemented with simple loops. We just have to loop through items in reverse instead of forward to get items from the end first and work towards the start.

The takeRight, tail and take methods can be implemented with slice .

reverse and slice methods are already built into plain JavaScript and it’s with Lodash uses anyways, so we can just use the plain JavaScript versions.

Categories
Lodash

Lodash Array Joining and Filtering Methods We Can Implement Easily

Lodash is a very useful utility library that lets us work with objects and arrays easily.

However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.

In this article, we’ll look at how to implement some Lodash array manipulation methods ourselves, including intersectionBy , last , lastIndexOf , nth , pull , pullAll and join .

intersectionBy

The Lodash intersectionBy method is like the intersection in that it returns an array with the unique entries that are include in all arrays, except that we can pass in our own callback to compare the items our way instead of using the SameValueZero algorithm for comparison.

We can implement it ourselves by taking a callback which we call in the callback of the array instance’s every method as follows:

const intersection = (iteratee, ...arrs) => {
  let vals = [];
  for (const a of arrs[0]) {
    const inAllArrs = arrs.map(arr => arr.map(iteratee)).every((arr) => arr.map(iteratee).includes(iteratee(a)));
    if (inAllArrs) {
      vals.push(a)
    }
  }
  return [...new Set(vals)];
}

In the code above, we get a condition callback function and a list of arrs from the arguments.

Then we get the first array and loops through it. In the loop, we call the every method on arrs to check if each array includes the given item from the first array, which is one of the arrays we want to check.

Also, to check if the item is included or not in every array, we have to map all the entries with the iteratee before checking, including the includes method.

This way, we compare them after they’ve been converted with the iteratee function.

Then, in the end, we converted the added items to a set and then convert it back to an array with the spread operator to return an array with unique items.

join

The Lodash join method converts all elements of an array into a string separated by a separator.

It does the same thing as the plain JavaScript array’s join method except that the plain JavaScript version is called on an array instance. The Lodash join method takes the array as an argument.

For instance, we can implement our own Lodash join method as follows:

const join = (arr, separator) => arr.join(separator)

We can then call it as follows:

const result = join([1, 2, 3], ',')

Then we get result is 1,2,3 .

last

The last method returns the last element of an array. We can easily create our own function to return it as follows:

const last = arr => arr[arr.length - 1]

Then we can call it as follows:

const result = last([1, 2, 3])

And we get that result is 3 as we expected.

lastIndexOf

Lodash’s indexOf method can be implemented easily with the indexOf method in plain JavaScript.

Then we can implement it as follows:

const indexOf = (arr, value, from) => arr.lastIndexOf(value, from)

In the code above, we called the lastIndexOf method with the value we’re looking for and the value that we’re looking for starting from the from index and working towards the beginning.

Then we can call it as follows:

const result = indexOf([1, 2, 3], 2, 3)

and the result is 1.

nth

Lodash’s nth method returns the nth entry in the array. We can obviously implement this easily by getting the n-th entry with the bracket notation as follows:

const nth = (arr, index) => arr[index]

In the code above, we just return the item with the given array index.

Then we can call it as follows:

const result = nth([1, 2, 3], 2)

Then result is 3 since we’re getting the 3rd element.

pull

The Lodash pull method returns a new array with the given values in the array removed.

We can implement it ourselves easily with the filter method as follows:

const pull = (arr, ...values) => arr.filter(a => !values.includes(a))

In the code above, we just called the filter method and in the callback, we call the includes method as we did above to exclude the items that we include with values , which is created by spreading the values.

Then we can call it as follows:

const result = pull([1, 2, 3], 2, 3)

We get that result is [1] .

pullAll

pullAll is similar to pull , except that it takes an array instead of a list of arguments. We can implement it as follows:

const pullAll = (arr, values) => arr.filter(a => !values.includes(a))

Then when we call it as follows:

const result = pullAll([1, 2, 3], [2, 3])

We get the same result value as before.

Conclusion

The join and lastIndexOf methods are built into plain JavaScript, so we can easily use them to implement the Lodash join and lastIndexOf methods.

The nth method gets the nth entry of an array. We can just do that with the bracket notation.

pull and pullAll can easily be implemented with the filter method.

Categories
Lodash

Lodash Array Methods That Can Easily Be Implemented in Plain JavaScript

Lodash is a very useful utility library that lets us work with objects and arrays easily.

However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.

In this article, we’ll look at some array access methods that can be replaced with plain JavaScript easily.

head

The head method just gets the first element of an array. We can do that without much effort since the first version of JavaScript.

For instance, we can create our own head function as follows:

const head = (arr) => arr[0]

Then we can it as follows:

const result = head([1, 2, 3]);

and get 1 for result .

indexOf

The Lodash indexOf method finds the value from that’s between the first index that we can optionally specify or the beginning of the array and the end of the array.

The plain JavaScript indexOf does the same thing. The only difference is that it’s part of the array instance rather than passing the array into the indexOf method like we do with Lodash.

We can easily use the plain JavaScript’s indexOf method to create our own Lodash’s indexOf method as follows:

const indexOf = (arr, val, start = 0) => arr.indexOf(val, start);

In the code above, we called the plain JavaScript’sindexOf on arr . Then we just pass in val for the item to search for and start for the optional starting index to search for.

Both indexOf methods return the index of the first match. Then we can call it as follows:

const result = indexOf([1, 2, 3], 2, 1);

and we get 1 for result since 2 is in index 1. Both indexOf methods return -1 is the item isn’t found within the range of the index specified.

initial

The Lodash initial method returns all but the last element of the array. We can easily implement this with the slice method.

For instance, we can implement it as follows:

const initial = (arr) => arr.slice(0, -1);

In the code above, we just called since with 0 and -1 as arguments to include the first to the 2nd last element. A negative index starts with -1 from the start to indicate the last element. Then the 2nd last is -2 and so on.

Therefore, when we call it as follows:

const result = initial([1, 2, 3]);

We get [1, 2] as the value of result .

intersection

The Lodash intersection method creates an array of unique values that are included in all the arrays given using SameValueZero equality comparison, which is similar to === except that +0 and -0 are considered different and NaN is the same as itself.

Lodash’s intersection method takes zero or more arrays arguments. We can get all the elements that are in all the arrays as follows:

const intersection = (...arrs) => {
  let vals = [];
  const longestArr = arrs.sort((a, b) => b.length - a.length)[0]
  for (const a of longestArr) {
    const inAllArrs = arrs.every((arr) => arr.includes(a))
    if (inAllArrs) {
      vals.push(a)
    }
  }
  return [...new Set(vals)];
}

In the code above, we first spread the arguments into an array.

Then we loop through the longest array and check if the other arrays have the same entries as the first array with the plain JavaScript’s every method with the callback (arr) => arr.includes(a) , which checks if all the arrays that are passed in include the given entry a .

We don’t have to check all arrays for all entries because if the one we loop through doesn’t have an item, then it shouldn’t be included anyways.

If it’s included in all arrays, then we push it to vals . includes uses the SameValueZero algorithm so that we don’t have to do any other checks for comparison.

Then when we call it as follows:

const result = intersection([1, 2, 3], [1, 2], [1, 3, 5]);

We get [1] as the value of result .

Conclusion

The Lodash head method doesn’t need much effort to implement ourselves since the first version of JavaScript.

The indexOf method can also be easily implemented with the plain JavaScript’s indexOf method.

We can use the slice method to implement the initial method of Lodash.

The intersection method can be implemented by using the spread operator to spread the arguments into an array and then use the for...of loop to loop through the longest array and check if the other arrays have the given entry.

Categories
Lodash

Useful Lodash Array Methods not Available in Plain JavaScript

Even though a few Lodash utility methods have been replaced by built-in methods in plain JavaScript, many still have no equivalent in the JavaScript standard library.

In this article, we’ll look at some Lodash array methods that aren’t in plain JavaScript.

_.take(array, [n=1])

The take method creates a slice of an array from the beginning and returns it.

It takes an array as the first argument and the number of elements n to get from the beginning as the second. n defaults to 1.

For instance, we can use it as follows:

import * as _ from "lodash";

const array = [1, 2, 3, 4, 5];
const arr = _.take(array, 2);

The code above takes the first 2 elements of array , creates a new array and returns it.

Therefore, arr has the value [1, 2] .

If we pass in 0 as the second argument, we get an empty array. If we pass in nothing, we get [1] as the value of arr .

_.takeRight(array, [n=1])

takeRight is like take but creates an array by taking the values starting from the end and returns it.

It takes an array as the first argument and the number of elements n to get from the beginning as the second. n defaults to 1.

For instance, we can use it as follows:

import * as _ from "lodash";

const array = [1, 2, 3, 4, 5];
const arr = _.takeRight(array, 2);

Then arr is [4, 5] because we passed in 2, which takes the last 2 values of array , creates a new array and then returns it.

If we pass in 0 as the second argument, we get an empty array. If we pass in nothing, we get [5] as the value of arr .

_.takeRightWhile(array, [predicate=_.identity])

We can use takeRightWhile top take elements from the end with the given condition and returns it.

Elements are taken until predicate returns a falsy value.

The predicate runs with 3 arguments, which are value , index , and array .

For instance, we can write the following code to extract active users from an array of users:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeRightWhile(users, value => value.active);

The code above sets:

[
  {
    "user": "baz",
    "active": true
  }
]

for activeUsers because it takes all the values that have active set to true until it finds one with active set to false .

Therefore, 'baz' meets that condition, so it’s put into the returned array.

On the other hand, the following:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: false }
];

const activeUsers = _.takeRightWhile(users, value => value.active);

assigns activeUsers to an empty array because the last entry has active set to false , so it never reaches one with active set to true .

Other ways to set predicate includes:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: false }
];

const inactiveUsers = _.takeRightWhile(users, { user: "baz", active: false });

Which checks the value of user and active in each entry.

Or we can write:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: false }
];

const inactiveUsers = _.takeRightWhile(users, ["active", false]);

which checks if the active property is false and get those entries.

Or we can write:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeRightWhile(users, "active");

to check is active is true .

_.takeWhile(array, [predicate=_.identity])

takeWhile returns a slice of the original array by checking the values from the start.

Elements are taken until predicate returns falsy. The predicate is run with 3 arguments, value , index , and array .

For example, we can write the following code to take values from the users array with active set to true from checking from the beginning of it:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeWhile(users, value => value.active);

The code above sets:

[
  {
    "user": "foo",
    "active": true
  }
]

to activeUsers because it checks at the first entry from the start has active set to true , so it takes that one and put it into the returned array.

Then the second has active set to false so it just returns the array with that entry included.

We can also write the following:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeWhile(users, { user: "foo", active: false });

to returns all the users entries with user value 'foo' and active set to false .

Likewise, we can write the following:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeWhile(users, ["active", true]);

to get all the entries with active set to true until one with active set to false is found.

To make the code even shorter, we can write:

import * as _ from "lodash";

const users = [
  { user: "foo", active: true },
  { user: "bar", active: false },
  { user: "baz", active: true }
];

const activeUsers = _.takeWhile(users, "active");

to make do the same thing as the previous example.

Conclusion

Lodash provides us with many ways to get an array that takes the entries that meet our condition until it finds one that doesn’t meet the condition we set.

These methods have no equivalent in JavaScript’s standard library, but they’re nevertheless useful for many.