Code Monkey home page Code Monkey logo

phase-0-intro-to-js-2-array-methods's Introduction

Array Methods

Learning Goals

  • Add elements to an Array
  • Remove elements from an Array
  • Replace elements in an Array

Introduction

In the last lesson, we learned about JavaScript Arrays, including how to create them and access their elements. In this lab, we will dive into JavaScript's Array methods, which enable us to add, remove, and change elements.

We discussed the fact that it's important to pay attention to whether the method is destructive (i.e., it mutates the array) or nondestructive. Another factor to pay attention to is what the return value of each of these methods is. Be sure to follow along and experiment with each method in replit until you understand how it works, what it does to the original array, and what it returns.

Add Elements to an Array

We'll start with the JavaScript methods we can use to add elements to an array: .push() and .unshift(), which are destructive methods, and the spread operator, which is nondestructive.

.push() and .unshift()

These two methods work in the same way:

  • They take one or more arguments (the element or elements you want to add)
  • They return the length of the modified array
  • They are destructive methods

The difference is that the .push() method adds elements to the end of an Array and .unshift() adds them to the beginning of the array:

const superheroes = ["Catwoman", "Storm", "Jessica Jones"];

superheroes.push("Wonder Woman");
// => 4

superheroes;
// => ["Catwoman", "Storm", "Jessica Jones", "Wonder Woman"]

const cities = ["New York", "San Francisco"];

cities.unshift("Boston", "Chicago");
// => 4

cities;
// => ["Boston", "Chicago", "New York", "San Francisco"]

Before moving on, try out the examples above as well as some examples of your own in the REPL.

Spread Operator

The spread operator, which looks like an ellipsis: ..., allows us to "spread out" the elements of an existing Array into a new Array, creating a copy:

const coolCities = ["New York", "San Francisco"];

const copyOfCoolCities = [...coolCities];

copyOfCoolCities;
//=> ["New York", "San Francisco"]

You might wonder why we would do this rather than just copyOfCoolCities = coolCities. The answer is that coolCities points to a location in memory and when you use the assignment operator to create a copy, you create a second variable that points to the same location. What this means is that, if you change copyOfCoolCities, coolCities is changed as well (and vice versa).

A note about copying arrays in JavaScript Copying arrays in JavaScript is complicated! Some methods of copying create deep copies and some create shallow copies. Using the spread operator to copy an array creates a shallow copy. What this means is that, if you use it to copy a nested array, the inner array (or arrays) still points to the same location in memory as in the original array. So if you modify the inner array in the copy, it changes the inner array in the original array as well (and vice versa). Don't worry too much about shallow and deep copies at this point: just know that you can safely use the spread operator to clone non-nested arrays.

Because the spread operator is an operator rather than a method, it works differently than push() and unshift(): in the example above, we're constructing an Array using literal notation (i.e., typing the square brackets) and populating it by using the spread operator on the Array we want to copy.

Where the spread operator comes in especially handy is when we want to add one or more new elements either before or after the elements in the original array (or both) without mutating the original array. To add an element to the front of the new array, we simply type in the new element before spreading the elements in the original array:

const coolCities = ["New York", "San Francisco"];

const allCities = ["Los Angeles", ...coolCities];

coolCities;
// => ["New York", "San Francisco"]

allCities;
// => ["Los Angeles", "New York", "San Francisco"]

And, as you might expect, to add a new item to the end of an Array, we type in the new element after spreading the elements in the original array:

const coolCats = ["Hobbes", "Felix", "Tom"];

const allCats = [...coolCats, "Garfield"];

coolCats;
// => ["Hobbes", "Felix", "Tom"]

allCats;
// => ["Hobbes", "Felix", "Tom", "Garfield"]

Note that, in both cases, we created a new Array instead of modifying the original one — our coolCities and coolCats Arrays were untouched. Because we didn't modify the original array, in order to save the results of our work we had to assign it to a variable.

Be sure to experiment with the spread operator in replit until you're comfortable with how it works — it will come in handy later!

Remove Elements from an Array

As complements for .push() and .unshift(), respectively, we have .pop() and .shift().

.pop() and .shift()

As with .push() and .unshift(), these two methods work in the same way:

  • they don't take any arguments
  • they remove a single element
  • they return the element that is removed
  • they are destructive methods

The .pop() method removes the last element in an Array:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.pop();
// => "Sun"

days;
// => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

The .shift() method removes the first element in an Array:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.shift();
// => "Mon"

days;
// => [Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

Notice above that both methods returned the removed element and mutated the original array.

.slice()

To remove elements from an Array nondestructively (without mutating the original Array), we can use the .slice() method. Just as the name implies, .slice() returns a portion, or slice, of an Array. The method takes 0, 1, or 2 arguments and returns a new array containing the sliced elements.

With No Arguments

If we don't provide any arguments, .slice() will return a copy of the original Array with all elements intact:

const primes = [2, 3, 5, 7];

const copyOfPrimes = primes.slice();

primes;
// => [2, 3, 5, 7]

copyOfPrimes;
// => [2, 3, 5, 7]

Note that creating a copy using .slice() works the same way as if you use the spread operator: they both create a shallow copy, and with both the copy points to a different object in memory than the original. If you add an element to one of the arrays, it does not get added to the others:

const primes = [2, 3, 5, 7];

const copyOfPrimesUsingSlice = primes.slice();

const copyOfPrimesUsingSpreadOperator = [...primes];

primes.push(11);
// => 5

primes;
// => [2, 3, 5, 7, 11]

copyOfPrimesUsingSlice;
// => [2, 3, 5, 7]

copyOfPrimesUsingSpreadOperator;
// => [2, 3, 5, 7]

With Arguments

We can also provide one or two arguments to .slice(): the first is the index where the slice should begin and the second is the index before which it should end:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.slice(2, 5);
// => ["Wed", "Thu", "Fri"]

If no second argument is provided, the slice will run from the index specified by the first argument to the end of the Array:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.slice(5);
// => ["Sat", "Sun"]

To return a new Array with the first element removed, we call .slice(1):

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.slice(1);
// => ["Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

And we can return an array with the last element removed in a way that will look familiar from the previous lesson:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.slice(0, days.length - 1);
// => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

However, .slice() provides an easier syntax for referencing the last element (or elements) in an Array:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.slice(-1);
// => ["Sun"]

days.slice(-3);
// => ["Fri", "Sat", "Sun"]

days.slice(0, -1);
// => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

When we provide a negative index, the JavaScript engine knows to start counting from the last element in the Array instead of the first.

.splice()

Unlike .slice(), which is nondestructive, .splice() performs destructive actions. Depending on how many arguments we give it, .splice() allows us to remove elements, add elements, or replace elements (or any combination of the three).

With a Single Argument

array.splice(start);

The first argument expected by .splice() is the index at which to begin the splice. If we only provide the one argument, .splice() will destructively remove a chunk of the original Array beginning at the provided index and continuing to the end of the Array:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.splice(2);
// => ["Wed", "Thu", "Fri", "Sat", "Sun"]

days;
// => ["Mon", "Tue"]

Notice that .splice() both mutated the original array (by removing a chunk, leaving just ["Mon", "Tue"]) and returned a new array containing the removed chunk.

We can use a negative 'start' index with splice(), the same as with slice():

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
// => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

days.splice(-2);
// => ["Sat", "Sun"]

days;
// => ["Mon", "Tue", "Wed", "Thu", "Fri"]

With Two Arguments

array.splice(start, deleteCount);

When we provide two arguments to .splice(), the first is still the index at which to begin splicing, and the second dictates how many elements we want to remove from the Array. For example, to remove 3 elements, starting with the element at index 2:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
// => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

days.splice(2, 3);
// => ["Wed", "Thu", "Fri"]

days;
// => ["Mon", "Tue", "Sat", "Sun"]

Here again, we see that splice() removed elements from the original array, mutating that array, and returned the removed elements in a new array.

Replace Elements in an Array

.splice() with 3+ arguments

array.splice(start, deleteCount, item1, item2, ...)

After the first two, every additional argument passed to .splice() will be inserted into the Array at the position indicated by the first argument. We can replace a single element in an Array as follows, discarding a card and drawing a new one:

const cards = [
  "Ace of Spades",
  "Jack of Clubs",
  "Nine of Clubs",
  "Nine of Diamonds",
  "Three of Hearts",
];

cards.splice(2, 1, "Ace of Clubs");
// => ["Nine of Clubs"]

cards;
// => ["Ace of Spades", "Jack of Clubs", "Ace of Clubs", "Nine of Diamonds", "Three of Hearts"]

We have deleted "Nine of Clubs" and inserted "Ace of Clubs" in place, effectively replacing the original card.

Or we can remove two elements and insert three new ones as our restaurant expands its vegetarian options:

const menu = [
  "Jalapeno Poppers",
  "Cheeseburger",
  "Fish and Chips",
  "French Fries",
  "Onion Rings",
];

menu.splice(1, 2, "Veggie Burger", "House Salad", "Teriyaki Tofu");
// => ["Cheeseburger", "Fish and Chips"]

menu;
// => ["Jalapeno Poppers", "Veggie Burger", "House Salad", "Teriyaki Tofu", "French Fries", "Onion Rings"]

We aren't required to remove anything with .splice() — we can use it to insert any number of elements anywhere within an Array by passing 0 as the second argument. Here we're adding new books to our library in alphabetical order:

const books = ["Beloved", "Giovanni’s Room", "The Color Purple", "The Grass Dancer"];

books.splice(2, 0,  "Kindred", "Love Medicine");
// => []

books;
// => ['Beloved', 'Giovanni’s Room', 'Kindred', 'Love Medicine', 'The Color Purple', 'The Grass Dancer']

Notice that .splice() returns an empty Array when we provide a second argument of 0. This makes sense because the return value is the set of elements that were removed, and we're telling it to remove 0 elements.

Keep playing around with .splice() in the REPL to get comfortable with it.

Using Bracket Notation to Replace Elements

Recall from the previous lesson that we can also use bracket notation to replace a single element in an Array. If we only need to replace one element, this is a simpler approach:

const cards = [
  "Ace of Spades",
  "Jack of Clubs",
  "Nine of Clubs",
  "Nine of Diamonds",
  "Three of Hearts",
];

cards[2] = "Ace of Clubs";
// => "Ace of Clubs"

cards;
// => ["Ace of Spades", "Jack of Clubs", "Ace of Clubs", "Nine of Diamonds", "Three of Hearts"]

Both this approach and splice() are destructive — they modify the original Array. There's a nondestructive way to replace or add items at arbitrary points within an Array; to do it we need to combine the slice() method and the spread operator.

Slicing and Spreading

Combining .slice() and the spread operator allows us to replace elements nondestructively, leaving the original Array unharmed:

const menu = [
  "Jalapeno Poppers",
  "Cheeseburger",
  "Fish and Chips",
  "French Fries",
  "Onion Rings",
];

const newMenu = [
  ...menu.slice(0, 1),
  "Veggie Burger",
  "House Salad",
  "Teriyaki Tofu",
  ...menu.slice(3),
];

menu;
// => ["Jalapeno Poppers", "Cheeseburger", "Fish and Chips", "French Fries", "Onion Rings"]

newMenu;
// => ["Jalapeno Poppers", "Veggie Burger", "House Salad", "Teriyaki Tofu", "French Fries", "Onion Rings"]

Let's unpack this a little bit. We're assigning an array to newMenu using literal notation. Inside the brackets, we are spreading the result of calling slice on menu with the arguments 0 and 1, then typing in three new elements, then spreading the result of calling slice on menu with the argument 3. Here, we are taking advantage of the fact that the slice() method returns a new array. We can spread the elements in that array just as we can with any other array.

Play around with this in the REPL until it makes sense; break it down into its component parts and try each piece on its own. It's the trickiest thing that we've encountered in this lesson, so don't sweat it if it takes a little while to sink in!

Conclusion

In this lesson, we've learned a variety of methods we can use to remove, add, and replace the elements in Arrays. We've learned that some methods are destructive and some are nondestructive. With this knowledge, you have the tools you need to manipulate Arrays in very complex ways.

JavaScript Array Methods

Resources

phase-0-intro-to-js-2-array-methods's People

Contributors

aviflombaum avatar bal360 avatar brewchetta avatar gj avatar graciemcguire avatar ihollander avatar jeffkatzy avatar jlboba avatar lizbur10 avatar lukeghenco avatar sgharms avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phase-0-intro-to-js-2-array-methods's Issues

Array Methods

Canvas Link

https://learning.flatironschool.com/courses/4789/pages/array-methods?module_item_id=292513

Concern

Under Splice:

Notice that .splice() both mutated the original array (by removing a chunk) and returned a new array containing the removed chunk.

Shouldn't it read, "AND returned a new array containing the remaining chunk"? or the unremoved chunk?

Because in the example:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

days.splice(2);
// => ["Wed", "Thu", "Fri", "Sat", "Sun"]

days;
// => ["Mon", "Tue"]

It looks like Mon/Tue remained and wasn't removed.

Additional Context

No response

Suggested Changes

No response

Incorrect number of elements?

const cities = ['New York', 'San Francisco'];

cities.unshift('Boston', 'Chicago');
// => 3

// shouldn't this return a value of 4, not 3?

splice() return values

Canvas Link

https://my.learn.co/courses/647/pages/array-methods?module_item_id=82738

Concern

At the bottom of the Array Methods lesson, the JavaScript Array Methods jpg image shows a return value for .splice to be "A new array containing the removed elements". However, MDN indicates splice() returns a modified version of the existing array containing the specified elements.
slice() on the other hand does return a new array, however, in the image, the return value is "A new array containing the removed elements". This is a bit confusing. According to MDN, slice() returns the selected elements, not the removed elements.
Hope this helps.

Additional Context

This could be easily addressed by replacing the image with an updated version.

https://curriculum-content.s3.amazonaws.com/phase-0/array-methods/javascript-array-methods.jpg

Suggested Changes

Perhaps a less confusing return value for these might be:

.slice( )
A new array containing the the elements specified

.splice( )
The existing array containing the elements specified

(Great class by the way, thanks!)

" adding new books to our library in alphabetical order"???

Canvas Link

https://learning.flatironschool.com/courses/5185/pages/array-methods?module_item_id=396118

Concern

In "Replace Elements in an Array" we say:
Here we're adding new books to our library in alphabetical order:

But I don't understand how the following shows anything that's in alphabetical order. (Trying to make sense of "alphabetical order" seems to have been a waste of time, which leaves me frustrated as a reader)

const books = ["The Bluest Eye", "Kindred", "The Grass Dancer"];

books.splice(2, 0, "Giovanni’s Room", "The Color Purple");
// => []

books;
// => ["The Bluest Eye", "Kindred", "Giovanni’s Room", "The Color Purple", "The Grass Dancer"]

Additional Context

No response

Suggested Changes

Maybe:

  • make it more clear how "alphabetical order" applies to the example
    -or-
  • stop mentioning alphabetical order

Confusing explanation

With Arguments
We can also provide one or two arguments to .slice(): the first is the index where the slice should begin and the second is the index before which it should end:

It seems to me it should say "after which it should end". In the example days.slice(2,5) the slice produces an array with indexes 2-4 rather than 2-6 which is what I expected based on the explanation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.