freeCodeCamp / CurriculumExpansion

Creative Commons Attribution Share Alike 4.0 International
314 stars 105 forks source link

JS Basic Data Structures: Arrays & Objects #90

Closed bonham000 closed 7 years ago

bonham000 commented 7 years ago

This Issue Contains the Proposed Basic Data Structures Challenges

As referenced in the proposed JavaScript section to the Curriculum Expansion, we are adding a basic data structures section to the JavaScript curriculum. This issue contains the development of these challenges. All other advanced data structures will reside in the later optional section.

These challenges are assigned to @no-stack-dub-sack & @bonham000.

Arrays:

Objects:


bonham000 commented 7 years ago

Title: Add Key-Value Pairs to JavaScript Objects

Description: The next data structure we will discuss is the JavaScript object. Objects are a very fundamental part of JavaScript, in fact, you may have heard this line before: 'In JavaScript, everything is an object.' While an understanding of objects is important to understand the inner workings of JavaScript functions or JavaScript's object-oriented capabilities, JavaScript objects at a basic level are actually just key-value pair stores, a commonly used data structure. Here, we will confine our discussion to JavaScript objects in this capacity.

Key-value pair data structure go by different names depending on the language you are using and the specific details of the data structure. The terms dictionary, map, and hash table all refer to the notion of a data structure in which specific keys, or properties are mapped to specific values. For instance, consider the following:

let FCC_User = {
 username: 'awesome_coder',
 followers: 572,
 points: 1741,
 completedProjects: 15
};

We've just defined an object called FCC_User with four properties each of which map to a specific value. If you wanted to know the number of followers FCC_User has, you could access that property by writing FCC_User.followers — this is called dot notation. You could also access the property with brackets, like so: FCC_User['followers']. Notice with the bracket notation we enclosed followers in quotes. This is because the brackets actually allow us to pass a variable in to be evaluated as a property name. Keep this in mind for later.

Instructions: We've created a foods object here with three entries. Add three more entries: bananas with a value of 13, grapes with a value of 35, and strawberries with a value of 27.

// SEED CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28
};
// change code below this line
// SOLUTION CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28
};

foods.bananas = 13;
foods.grapes = 35;
foods.strawberries = 27;
// TESTS
assert(typeof foods === 'object', 'foods is an object');
assert(foods.bananas === 13, 'The foods object has a key \'bananas\' with a value of 13.');
assert(foods.grapes === 35, 'The foods object has a key \'grapes\' with a value of 35.');
assert(foods.strawberries === 27, 'The foods object has a key \'strawberries\' with a value of 27.');
bonham000 commented 7 years ago

Title: Modify an Object Nested Within an Object

Description: Objects, and other similar key-value pair data structures, offer some very useful benefits. One clear benefit is that they allow us to structure our data in an intuitive way. They are also very flexible. For instance, you can have properties nested to an arbitrary depth. Values can also be anything, for example a key can store an array, or even another object. Objects are also the foundation for JavaScript Object Notation, JSON, which is a widely used method of sending data across the web.

Another powerful advantage of key-value pair data structures is constant lookup time. What we mean by this is when you request the value of a specific property you will get the value back in the same amount of time (theoretically) regardless of the number of entries in the object. If you had an object with 5 entries or one that held a collection of 1,000,000 entries you could still retrieve property values or check if a key exists in the same amount of time.

The reason for this fast lookup time is that internally the object is storing properties using some type of hashing mechanism which allows it to know exactly where it has stored different property values. If you want to learn more about this please take a look at the optional Advanced Data Structures challenges. All you should remember for now is that performant access to flexibly structured data make key-value stores very attractive data structures useful in a wide variety of settings.

Instructions: Here we've written an object nestedObject which includes another object nested within it. You can modify properties on this nested object in the same way you modified properties in the last challenge. Set the value of the online key to 45.

// SEED CODE
let nestedObject = {
    id: 23894201352,
    date: 'January 1, 2017',
    data: {
        totalUsers: 51,
        online: 42
    }
};
// change code below this line
// SOLUTION CODE
let nestedObject = {
    id: 23894201352,
    date: 'January 1, 2017',
    data: {
        totalUsers: 51,
        online: 42
    }
};

nestedObject.data.online = 45;
// TESTS
assert('id' in nestedObject && 'date' in nestedObject && 'data' in nestedObject, 'nestedObject has id, date and data properties.');
assert('totalUsers' in nestedObject.data && 'online' in nestedObject.data, 'nestedObject has a data key set to an object with keys totalUsers and online.');
assert(nestedObject.data.online === 45, 'The online property nested in the data key of nestedObject should be set to 45.');
bonham000 commented 7 years ago

Title: Access Property Names with Bracket Notation

Description: In the first challenge we mentioned the use of bracket notation as a way access properties values using the evaluation of a variable. For instance, if you recall our foods object from that challenge, imagine that this object is being used in a program for a supermarket cash register. We have some function that sets the selectedFood and we want to check our foods object for the presence of that food. This might look like:

let selectedFood = getCurrentFood(scannedItem);
let inventory = foods[selectedFood];

This code will evaluate the value stored in the selectedFood variable and return the value of that key in the foods object, or undefined if it is not present. Bracket notation is very useful because sometime object properties are not known before runtime or we need to access them in a more dynamic way.

Instructions: In the example code we've defined a function checkInventory which receives a scanned item as an argument. Return the current value of the scannedItem key in the foods object. You can assume that only valid keys will be provided as an argument to checkInventory.

// SEED CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28,
    bananas: 13,
    grapes: 35,
    strawberries: 27
};

function checkInventory(scannedItem) {
    // change code below this line

    // change code above this line
};
// SOLUTION CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28,
    bananas: 13,
    grapes: 35,
    strawberries: 27
};

function checkInventory(scannedItem) {
    return foods[scannedItem];
};
// TESTS
assert(typeof checkInventory === 'function', 'checkInventory is a function');
assert('apples' in foods && 'oranges' in foods && 'plums' in foods && 'bananas' in foods && 'grapes' in foods && 'strawberries' in foods, 'The foods object contains the following keys: apples, oranges, plums, bananas, grapes, and strawberries.');
assert(checkInventory('apples') === 25 && checkInventory('bananas') === 13 && checkInventory('strawberries') === 27, 'The checkInventory function returns the value of the scannedItem argument in the foods object.');
bonham000 commented 7 years ago

Title: Use the Delete Keyword to Remove Object Properties

Description: Now you know what objects are and their basic features and advantages. In short, they are key-value stores which provide a flexible, intuitive way to structure data and they provide very fast lookup time. For the rest of these challenges, we will describe several common operations you can perform on objects so you can become comfortable applying these useful data structures in your programs.

Previously, we added and modified key-value pairs to objects. Here we will see how we can remove a key-value pair from an object. If we wanted to remove the apples key from our foods object from before, we could remove it by using the delete keyword like this:

delete foods.apples;

Instructions: Use the delete keyword to remove the oranges, plums, and strawberries keys from the foods object.

// SEED CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28,
    bananas: 13,
    grapes: 35,
    strawberries: 27
};
// change code below this line
// SOLUTION CODE
let foods = {
    apples: 25,
    oranges: 32,
    plums: 28,
    bananas: 13,
    grapes: 35,
    strawberries: 27
};

delete foods.oranges;
delete foods.plums;
delete foods.bananas;
// TESTS
assert(!foods.hasOwnProperty('oranges') && !foods.hasOwnProperty('plums') && !foods.hasOwnProperty('bananas') && Object.keys(foods).length === 3, 'The foods object only has three keys: apples, grapes, and strawberries.');
bonham000 commented 7 years ago

Title: Check if an Object has a Property

Description: Now we can add, modify, and remove keys from objects. But what if we just wanted to know if an object has a specific property? JavaScript provides two different ways to do this. One uses the hasOwnProperty method on the object and the other uses the in keyword. If we have an object users with a property of Alan, we could check for its presence in either of the following ways:

users.hasOwnProperty('Alan');
'Alan' in users;
// both return true

Instructions: We've created a users object here with some users in it and a function isEveryoneHere which we pass the users object to as an argument. Finish writing this function so that it returns true only if the users object contains all four names, Alan, Jeff, Sarah, and Ryan, as keys, and false otherwise.

SEED CODE
let users = {
    Alan: {
        age: 27,
        online: true
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: true
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function isEveryoneHere(obj) {
    // change code below this line

    // change code above this line
};
// SOLUTION CODE
let users = {
    Alan: {
        age: 27,
        online: true
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: true
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function isEveryoneHere(obj) { 
    return ('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users) ? true : false;
};
// TESTS
assert('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users && Object.keys(users).length === 4, 'The users object only contains the keys Alan, Jeff, Sarah, and Ryan.');
assert(isEveryoneHere(users) === true, 'The function isEveryoneHere returns true if Alan, Jeff, Sarah, and Ryan are properties on the users object');
assert((function() { delete users.Alan; delete users.Jeff; delete users.Sarah; delete users.Ryan; return isEveryoneHere(users) })() === false, 'The function isEveryoneHere returns false if Alan, Jeff, Sarah, and Ryan are not keys on the users object.');
bonham000 commented 7 years ago

Title: Iterate Through the Keys of an Object with a for...in Statement

Description: Sometimes you may need to iterate through all the keys within an object. This requires a specific syntax in JavaScript called a for...in statement. For our users object from the last challenge, this could look like:

for (let user in users) {
 console.log(user);
};

In this statement, we define a variable user. This variable will be set to the key in each iteration as the statement loops through the keys in the object. Running this code would print the name of each user to the console. Note that objects do not maintain an ordering to stored keys like arrays do.

Instructions: We've defined a function countOnline that should return the number of users with the online property set to true. Use a for...in statement within this function to loop through the users in the users object and return the number of users whose online property is set to true.

// SEED CODE
let users = {
    Alan: {
        age: 27,
        online: false
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: false
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function countOnline(obj) {
    // change code below this line

    // change code above this line
};
// SOLUTION CODE
let users = {
    Alan: {
        age: 27,
        online: false
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: false
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function countOnline(obj) { 
    let n = 0;
    for (let user in obj) if (obj[user].online) n++;
    return n;
};
// TESTS
assert(users.Alan.online === false && users.Jeff.online === true &&  users.Sarah.online === false &&  users.Ryan.online === true, 'The users object contains users Jeff and Ryan with online set to true and users Alan and Sarah with online set to false.');
assert((function() { users.Harry = {online: true}; users.Sam = {online: true}; users.Carl = {online: true}; return countOnline(users) })() === 5, 'The function countOnline returns the number of users with the online property set to true.');
bonham000 commented 7 years ago

Title: Generate an Array of All Object Keys with Object.keys()

Description: We can also generate an array which contains all the keys stored in an object using the Object.keys() method and passing in an object as the argument. This will return an array with strings representing each property in the object. Again, there will be no specific order to the entries in the array.

Instructions: Finish writing the getArrayOfUsers function so that it returns an array containing all the properties in the object it receives as an argument.

// SEED CODE
let users = {
    Alan: {
        age: 27,
        online: false
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: false
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function getArrayOfUsers(obj) {
    // change code below this line

    // change code above this line
};
// SOLUTION CODE
let users = {
    Alan: {
        age: 27,
        online: false
    },
    Jeff: {
        age: 32,
        online: true
    },
    Sarah: {
        age: 48,
        online: false
    },
    Ryan: {
        age: 19,
        online: true
    }
};

function getArrayOfUsers(obj) {
    return Object.keys(obj);
};
// TESTS
assert('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users && Object.keys(users).length === 4, 'The users object only contains the keys Alan, Jeff, Sarah, and Ryan.');
assert((function() { users.Sam = {}; users.Lewis = {}; let R = getArrayOfUsers(users); return (R.indexOf('Alan') !== -1 && R.indexOf('Jeff') !== -1 && R.indexOf('Sarah') !== -1 && R.indexOf('Ryan') !== -1 && R.indexOf('Sam') !== -1 && R.indexOf('Lewis') !== -1); })() === true, 'The getArrayOfUsers function returns an array which contains all the keys in the users array.');
bonham000 commented 7 years ago

Title: Modify an Array Stored in an Object

Description: Now you've seen all the basic operations for JavaScript objects. You can add, modify, and remove key-value pairs, check if keys exist, and iterate over all the keys in an object. As you continue learning JavaScript you will see even more versatile applications of objects. Additionally, the optional Advanced Data Structures lessons later in the curriculum also cover the ES6 Map and Set objects, both of which are similar to ordinary objects but provide some additional features. Now that you've learned the basics of arrays and objects, you're fully prepared to begin tackling more complex problems using JavaScript!

Instructions: Take a look at the object we've provided in the code editor. The user object contains three keys. The data key contains four keys, one of which contains an array of friends. From this, you can see how flexible objects are as data structures. We've started writing a function addFriend. Finish writing it so that it takes a user object and adds the name of the friend argument to the array stored in user.data.friends.

// SEED CODE
let user = {
    name: 'Kenneth',
    age: 28,
    data: {
        username: 'kennethCodesAllDay',
        joinDate: 'March 26, 2016',
        organization: 'Free Code Camp',
        friends: [
            'Sam',
            'Kira',
            'Tomo'
        ],
        location: {
            city: 'San Francisco',
            state: 'CA',
            country: 'USA'
        }
    }
};

function addFriend(user, friend) {
    // change code below this line  

    // change code above this line
};
// SOLUTION CODE
let user = {
    name: 'Kenneth',
    age: 28,
    data: {
        username: 'kennethCodesAllDay',
        joinDate: 'March 26, 2016',
        organization: 'Free Code Camp',
        friends: [
            'Sam',
            'Kira',
            'Tomo'
        ],
        location: {
            city: 'San Francisco',
            state: 'CA',
            country: 'USA'
        }
    }
};

function addFriend(user, friend) {
    user.data.friends.push(friend);
    return user;
};
// TESTS
assert('name' in user && 'age' in user && 'data' in user, 'The user object has name, age, and data keys');
assert((function() { let L1 = user.data.friends.length; addFriend(user, 'Sean'); let L2 = user.data.friends.length; return (L2 === L1 + 1); })(), 'The addFriend function accepts a user object and a friend as arguments and adds the friend to the array of friends in the user object.');
QuincyLarson commented 7 years ago

@bonham000 nice work. These look solid. Excellent explanations and examples so far.

no-stack-dub-sack commented 7 years ago

@QuincyLarson @bonham000 Should have these done by friday evening

no-stack-dub-sack commented 7 years ago

@bonham000 @QuincyLarson - I know we discussed trying not to include MDN links, but I think it is important for challenges like these. Mainly because, with topics like splice() for example, we simply can't cover everything without being overly verbose - for instance, covering the things like negative values for parameters and the result of omitting the second parameter - covering these intricacies would likely make the challenge convoluted and too wordy, but these are important things to learn. What do you guys think?

If we don't include the external links, we run the risk of it being said that the challenges aren't thorough or don't provide deep enough scope on a given topic. Including them covers our bases without us having to explicitly cover it.

ncovercash commented 7 years ago

I like the MDN links personally, very helpful for some api doc

ncovercash commented 7 years ago

are we going to use let as well now? We will need to cover that in the initial part of javascript if you havent already

no-stack-dub-sack commented 7 years ago

@smileytechguy For sure, most of the new ES6 features, including let and const statements, are going to be covered in the curriculum expansion - you can see a list of topics for that section here: #34.

QuincyLarson commented 7 years ago

@no-stack-dub-sack We will want to tell campers that "roughly, splice does..." and give them a high level overview. We aren't aiming to provide comprehensive definitions and descriptions. Rather, we just want them to understand it well enough to solve the challenge and keep moving.

The MDN is good, but it can be intimidating, and sometimes it takes several re-reads to understand the concept they're talking about. I say do your best to explain these briefly, and our community can amend your description as necessary in the future.

ncovercash commented 7 years ago

@no-stack-dub-sack what about older browsers? They won't work with FCC now...

ncovercash commented 7 years ago

@smileytechguy - thanks for contributing this challenge, but I'm taking away the H1 heading for now so there's no confusion when I post the version of the first challenge that had already been completed.

Use an array to store a collection of data

Description:

We have learned that we can use the let and var keywords in order to store data. However, what if we want to store a collection of data?

Imagine you had a bunch of coffee cups, and wanted to put them on a shelf. Rather than building an individual shelf for each cup, you would put them all on the same shelf.

In code, this also makes logical sense. Rather than making a variable for each one such as coffeCup1, coffeCup2, coffeCup3, coffeCup4, coffeCup5, you would make a "shelf" of them.

In JavaScript, these "shelfs" are called arrays. An array can store multiple variables in one variable, keeping them in order and much more.

In order to create an array, you use the following syntax:

var ourArray = [];

In the above example, the two brackets ([ and ]) denote array notation. They are used to start and end the array.

Whatever you want to put in the array goes within these brackets. For example, if you wanted to put the numbers 1, 2, and 3 in the array you would do the following:

ourArray = [1, 2, 3];

Anything can go in an array! This things include:

In order to pass this challenge, create an Array called myArray containing "a", "b", and "c".

Seed code

// create your array here!

Solution code

// create your array here!
var myArray = ["a", "b", "c"];

or

// create your array here!
let myArray = ["a", "b", "c"];

Tests

assert(Array.isArray(myArray), '`myArray` is an array');
assert(myArray === ["a", "b", "c"], '`myArray` contains `"a"`, `"b"`, and `"c"`');
ncovercash commented 7 years ago

Access an array's contents using bracket notation

I would like to add this challenge, as it is too much to combine with the above.

Description

In the previous challenge, we learned how to create an array. Now, we want to access this information.

When we define a simple array as seen below, there are 3 items in it:

var ourArray = ["a", "b", "c"];

In an array, each array item has an index. This index doubles as the position in the array, as well as how you reference it.

However, it is important to note, that JavaScript arrays are zero-indexed, meaning that the first element of an array is actually at the zeroth position, not the first.

In order to retrieve an element from an array we can use the index in combination with brackets.

For example, if we want to get the "a" from ourArray and assign it to a variable, we can do so with the following snippet:

let ourVariable = ourArray[0];
// ourVariable equals "a"

Besides accessing the value associated with an index, you can set an index to a value using the same notation:

ourArray[1] = "not b anymore";

The above line would set index 1 in ourArray, which was "b", to "not b anymore".

In order to complete this challenge, set the 2nd position (1st index) of myArray to anything you want (besides "b").

Seed code

let myArray = ["a", "b", "c", "d"];
// write your code below this line

Solution code

let myArray = ["a", "b", "c", "d"];
// write your code below this line
myArray[1] = "literally anything";

Tests

assert.strictEqual(myArray[0], "a", '<code>myArray[0]</code> is equal to <code>"a"</code>.');
assert.notStrictEqual(myArray[1], "b", '<code>myArray[1]</code> is no longer set to <code>"b"</code>');
assert.strictEqual(myArray[2], "c", '<code>myArray[0]</code> is equal to <code>"c"</code>.');
assert.strictEqual(myArray[3], "d", '<code>myArray[0]</code> is equal to <code>"d"</code>.');
ncovercash commented 7 years ago

I will try to do all of the following:

 Add items to an array with push() and unshift()
 Remove items from an array with pop() and shift()
 Remove items using splice()
 Add items using splice()
 Copy an array with slice()
 Copy an array with spread syntax
 Check for the presence of an item with indexOf()
 Iterate through all the items in an array
 Create a nested array
bonham000 commented 7 years ago

Hey @smileytechguy I believe at the moment @no-stack-dub-sack is working on developing these array challenges, I think he already has some work completed for several of these, just not finalized and added here yet.

ncovercash commented 7 years ago

@bonham000 oh alright, sure

bonham000 commented 7 years ago

However, @smileytechguy, while we wait for his response if you are still looking to contribute here, the challenges on objects that I've already added have not been reviewed or QA'd by anyone. This will still need to occur before these challenges are actually seeded into the curriculum. If you're interested in looking over them to review them, that would be really helpful.

ncovercash commented 7 years ago

@bonham000 ill review them in a few

no-stack-dub-sack commented 7 years ago

@bonham000 @smileytechguy Hey guys, sorry for the confusion - I suppose I should have been at least checking off what was done as I completed them locally. I was just waiting til they were all done to post them to make it more streamlined. I have just checked off the ones I have completed and should be getting to the rest tonight.

@smileytechguy

what about older browsers? They won't work with FCC now...

Is this from our conversation about ES6?

QuincyLarson commented 7 years ago

@no-stack-dub-sack Ok - excellent. I'm stoked to see them and get them imported into our curriculum.

ncovercash commented 7 years ago

@no-stack-dub-sack yes, that was about the conversion to ES6 . if there are any you want me to do, let me know

no-stack-dub-sack commented 7 years ago

@smileytechguy Sure! I've gotten all done but one at this point, the insert items with spread syntax challenge, which I just added to the list as sort of an afterthought, but if you want to do it, go for it!

The idea we had in having @bonham000 and I each tackle one of these sections in whole, was to keep the narrative consistent throughout, so if you'd like to do it, if you don't mind, just take a quick look at how I did the preceding spread syntax challenge here, and try to keep the narrative/writing consistent so our users will have a clean experience moving from one challenge to the next.

I think the challenge you wrote on bracket notation was much needed, and I've added it to the list, but if it's cool with you, I might make some small edits before we seed it so that it matches the rest of the ones I wrote in order to keep with the same theme of keeping narrative clear and consistent.

Thoughts? Thanks again for pitching in!

no-stack-dub-sack commented 7 years ago

@bonham000 @QuincyLarson Though I've checked them as complete, I have not posted them yet. Will be doing that early tomorrow once I give them a last once over to hopefully minimize the work on QAs end.

no-stack-dub-sack commented 7 years ago

@smileytechguy As mentioned in my previous post, I went through and made a couple of changes to your "Access elements" challenge to keep the narrative clean throughout. I'm also going to post my version of the first challenge because it sets up some other things for the rest of the challenges. Sorry for the confusion, I just hadn't posted mine yet since the OP mentioned they had been assigned.

also, I wasn't sure about this test, so I took it out for now... where is the code variable coming from?

assert(code.split(/(myArray = )/g).length === code.split(/(myArray = )/g).length, "`myArray` is only declared once`");
no-stack-dub-sack commented 7 years ago

Use an array to store a collection of data

Description:

Arrays are JavaScript's most fundamental, and perhaps most common, data structure. An array is simply a collection of data, of any length (zero-indexed), arranged in a comma separated list and enclosed in brackets [ ]. While we often make the distinction in JavaScript between Objects and Arrays, it is important to note that technically, an array is a type of object.

Arrays can store any type of data supported by JavaScript, and while they are a simple and basic form of data structure, they can also be very complex and powerful - all of which depends on how the programmer utilizes them.

The below is an example of a valid array, notice it contains booleans, strings, numbers, other arrays (this is called a nested, or multi-dimensional array), and objects, among other valid data types:

let myArray = [undefined, null, true, false, 'one', 2, "III", {'four': 5}, [6, 'seven', 8]];

JavaScript offers many built in methods which allow us to access, traverse, and mutate arrays as needed, depending on our purpose. In the coming challenges, we will discuss several of the most common and useful methods, and a few other key techniques, that will help us to better understand and utilize arrays as data structures in JavaScript.

Instructions

We have defined a variable called yourArray; complete the declaration by defining an array of at least 5 elements in length. Your array should contain at least one string, one number, and one boolean.

Challenge Seed:

let yourArray = // change code here;

Challenge Solution:

let yourArray = [true, false, 'one', 2, 'III'];

Tests:

assert.strictEqual(Array.isArray(yourArray), true, 'yourArray is an array.');
assert(yourArray.length >= 5, 'yourArray is at least 5 elements long.')
assert(yourArray.filter( el => typeof el === 'boolean').length >= 1, '<code>yourArray</code> contains at least one boolean.');
assert(yourArray.filter( el => typeof el === 'number').length >= 1, '<code>yourArray</code> contains at least one number.');
assert(yourArray.filter( el => typeof el === 'string').length >= 1, '<code>yourArray</code> contains at least one string.');
no-stack-dub-sack commented 7 years ago

Add items to an array with push() and unshift()

Description:

An array's length, like the data types it can contain, is not fixed. Arrays can be defined with a length of any number of elements, and elements can be added or removed over time. In this challenge, we will look at two methods with which we can programmatically modify an array: Array.push() and Array.unshift().

Both methods take one or more elements as parameters and add those elements to the array the method is being called on; the push() method adds elements to the end of an array, and unshift() adds elements to the beginning. Consider the following:

let twentyThree = 'XXIII';
let romanNumerals = ['XXI', 'XXII'];

romanNumerals.unshift('XIX', 'XX'); 
// now equals ['XIX', 'XX', 'XXI', 'XXII']
romanNumerals.push(twentyThree); 
// now equals ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']

Notice that we can also pass variables, which allows us even greater flexibility in dynamically modifying our array's data.

Instructions:

We have defined a function, mixedNumbers, which we are passing an array as an argument. Modify the function by using push() and shift() to add 'I', 2, 'three', to the beginning of the array and 7, 'VIII', '9' to the end so that the returned array contains representations of the numbers 1-9 in order.

Challenge Seed:

function mixedNumbers(arr) {
    // change code below this line

    // change code above this line
    return arr;
}

// do not change code below this line
mixedNumbers(['IV', 5, 'six'])

Challenge Solution

function mixedNumbers(arr) {
    arr.push(7, 'VIII', '9');
    arr.unshift('I', 2, 'three');
    return arr;
}

Tests:

assert.deepEqual(mixedNumbers(['IV', 5, 'six']), ['I', 2, 'three', 'IV', 5, 'six', 7, 'VIII', '9'], "<code>mixedNumbers(['IV', 5, 'six'])</code> should now return <code>['I', 2, 'three', 'IV', 5, 'six', 7, 'VIII', '9']</code>");
assert.notStrictEqual(mixedNumbers.toString().search(/\.push\(/), -1, "The <code>mixedNumbers</code> function should utilize the <code>push()</code> method."); 
assert.notStrictEqual(mixedNumbers.toString().search(/\.unshift\(/), -1, "The <code>mixedNumbers</code> function should utilize the <code>unshift()</code> method."); 
no-stack-dub-sack commented 7 years ago

Remove items from an array with pop() and shift()

Instructions

Both push() and unshift() have corresponding methods that are nearly functional opposites: pop() and shift(). As you may have guessed by now, instead of adding, pop() removes an element from the end of an array, while shift() removes an element from the beginning. The key difference between pop() and shift() and their cousins push() and unshift(), is that neither method takes parameters, and each only allows an array to be modified by a single element at a time.

Let's take a look:

let greetings = ['whats up?', 'hello', 'see ya!'];

greetings.pop() 
// now equals ['whats up?', 'hello']
greetings.shift() 
// now equals ['hello']

We can also return the value of the removed element with either method like this:

let popped = greetings.pop(); 
// returns 'hello'
// greetings now equals []

Instructions

We have defined a function, popShift, which takes an array as an argument and returns a new array. Modify the function, using pop() and shift(), to remove the first and last elements of the argument array, and assign the removed elements to their corresponding variables, so that the returned array contains their values.

Challenge Seed

function popShift(arr) {
    let popped = // change code here
    let shifted = // change code here
    return [shifted, popped];
}

// do not change code below this line
popShift(['challenge', 'is', 'not', 'complete']);

Challenge Solution

function popShift(arr) {
    let popped = arr.pop();
    let shifted = arr.shift();
    return [shifted, popped];
}

Tests

assert.deepEqual(popShift(['challenge', 'is', 'not', 'complete']), ['challenge', 'complete'], "<code>popShift(['challenge', 'is', 'not', 'complete'])</code> should return <code>['challenge', 'complete']</code>.");
assert.notStrictEqual(popShift.toString().search(/\.pop\(/), -1, "The <code>popShift</code> function should utilize the <code>pop()</code> method."); 
assert.notStrictEqual(popShift.toString().search(/\.shift\(/), -1, "The <code>popShift</code> function should utilize the <code>shift()</code> method."); 
no-stack-dub-sack commented 7 years ago

Remove items using splice()

Instructions

Ok, so we've learned how to remove elements from the beginning and end of arrays using pop() and shift(), but what if we want to remove an element from somewhere in the middle? Or remove more than one element at once? Well, that's where splice() comes in. splice() allows us to do just that: remove any numnber of consecutive elements from anywhere on an array.

splice() can take up to 3 parameters, but for now, we'll focus on just the first 2. The first two parameters of splice() are integers which represent indexes, or postions, of the array that splice() is being called upon. And remember, arrays are zero-indexed, so to indicate the first element of an array, we would use 0. splice()'s first parameter represents the index on the array from which to begin removing elements, while the second parameter indicates the number of elements to delete. For example:

let array = ['today', 'was', 'not', 'so', 'great'];
array.splice(2, 2); 
// indicates that splice() should remove 2 elements beginning with the 3rd element
// array now equals ['today', 'was', 'great']

splice() not only modifies the array it is being called on, but it also returns a new array containing the value of the removed elements. For example:

let array = ['today', 'was', 'not', 'so', 'great'];
let newArray = array.splice(3, 2); 
// newArray equals ['so', 'great']

Instructions

We've defined a function, sumOfTen, which takes an array as an argument and returns the sum of that array's elements. Modify the function, using splice(), so that it returns a value of 10.

Challenge Seed

function sumOfTen(arr) {
    // change code below this line

    // change code above this line
    return arr.reduce((a, b) => a + b);
}

// do not change code below this line
sumOfTen([2, 5, 1, 5, 2, 1]);

Challenge Solution

function sumOfTen(arr) {
    arr.splice(1, 2);
    return arr.reduce((a, b) => a + b);
}

Tests

assert.strictEqual(sumOfTen([2, 5, 1, 5, 2, 1]), 10, "<code>sumOfTen</code> should return 10.");
assert.notStrictEqual(sumOfTen.toString().search(/\.splice\(/), -1, "The <code>sumOfTen</code> function should utilize the <code>splice()</code> method.")
no-stack-dub-sack commented 7 years ago

Add items using splice()

Instructions

Remember in the last challenge we mentioned that splice() can take up to three parameters? Well, we can go one step further with splice() — in addition to removing elements, we can use that third parameter, which represents one or more elements, to add them as well. This can be incredibly useful for quickly switching out an element, or a set of elements, for another. For instance, let's say you're storing a color scheme for a set of DOM elements in an array, and want to dynamically change a color based on some action:

function colorChange(arr, index, newColor) {
    arr.splice(index, 1, newColor);
    return arr;
} 

let colorScheme = ['#878787', '#a08794', '#bb7e8c', '#c9b6be', '#d1becf'];
colorScheme = colorChange(colorScheme, 2, "#332327");
// we have removed '#bb7e8c' and added '#332327' in its place
// colorScheme now equals ['#878787', '#a08794', '#332327', '#c9b6be', '#d1becf']

This function takes an array of hex values, an index at which to remove an element, and the new color to replace the removed element with. The return value is an array containing a newly modified color scheme! While this example is a bit oversimplified, we can see the value that utilizing splice() to its maximum potential can have.

Instructions

We have defined a function, htmlColorNames, which takes an array of html colors as an argument. Modify the function using splice() to remove the first two elements of the array and add 'DarkSalmon' and 'BlanchedAlmond' in their respective places.

Challenge Seed

function htmlColorNames(arr) {
    // change code below this line

    // change code above this line
    return arr;
} 

// do not change code below this line
htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']);

Challenge Solution

function htmlColorNames(arr) {
    arr.splice(0, 2, 'DarkSalmon', 'BlanchedAlmond');
    return arr;
} 

Tests

assert.deepEqual(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']), ['DarkSalmon', 'BlanchedAlmond', 'LavenderBlush', 'PaleTurqoise', 'FireBrick'], "<code>htmlColorNames</code> should return ['DarkSalmon', 'BlanchedAlmond', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']");
assert.notStrictEqual(htmlColorNames.toString().search(/\.splice\(/), -1, "The <code>htmlColorNames</code> function should utilize the <code>splice()</code> method.")
no-stack-dub-sack commented 7 years ago

Copy an array with slice()

Instructions

The next method we will cover is slice(). slice(), rather than modifying an array, copies, or extracts, a given mumber of elements to a new array, leaving the array it is called upon untouched. slice() takes only 2 parameters — the first is the index at which to begin extraction, and the second is the index at which to stop extraction (extraction will occur up to, but not including the element at this index). Consider this:

let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
let todaysWeather = weatherConditions.slice(1, 3);
// todaysWeather equals ['snow', 'sleet'];
// weatherConditions still equals ['rain', 'snow', 'sleet', 'hail', 'clear']

In effect, we have created a new array by extracting elements from an existing array.

Instructions

Instructions: We have defined a function, forecast, that takes an array as an argument. Modify the function using slice() to extract information from the argument array and return a new array that contains the elements 'warm' and 'sunny'.

Challenge Seed

function forecast(arr) {
    // change code below this line

    return arr;
}

// do not change code below this line
forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']);

Challenge Solution

function forecast(arr) {
    return arr.slice(2, 4);
}

Tests

assert.deepEqual(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']), ['warm', 'sunny'], "<code>forecast</code> should return <code>['warm', 'sunny'].");
assert.notStrictEqual(forecast.toString().search(/\.slice\(/), -1, "The <code>forecast</code> function should utilize the <code>slice()</code> method.");
no-stack-dub-sack commented 7 years ago

Copy an array with spread syntax

Instructions

While slice() allows us to be selective about what elements of an array to copy, ammong several other useful tasks, ES6's new spread syntax allows us to easily copy all of an array's elements, in order, with a simple and highly readable syntax. The spread syntax simply looks like this: ...

In practice, we can use the spread syntax to copy an array like so:

let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];
// thatArray equals [true, true, undefined, false, null]
// thisArray remains unchanged, and is identical to thatArray

Instructions

We have defined a function, copyMachine which takes arr (an array) and num (a number) as arguments. The function is supposed to return a new array made up of num copies of arr. We have done most of the work for you, but it doesn't work quite right yet. Modidy the function using the spead syntax so that it works correctly (hint: another method we have already covered might come in handy here!).

Challenge Seed

function copyMachine(arr, num) {
    let newArr = [];
    while (num >= 1) {
    // change code below this line

    // change code above this line
    num--;
    }
    return newArr;
}

copyMachine([true, false, true], 2);

Challenge Solution

function copyMachine(arr, num) {
    let newArr = [];
    while (num >= 1) {
    newArr.push([...arr]);
    num--;
    }
    return newArr;
}

Tests

assert.deepEqual(copyMachine([true, false, true], 2), [[true, false, true], [true, false, true]], "<code>copyMachine([true, false, true], 2)</code> should return <code>[[true, false, true], [true, false, true]]</code>.")
assert.deepEqual(copyMachine([1, 2, 3], 5), [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]], "<code>copyMachine([1, 2, 3], 5)</code> should return <code>[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]</code>.");
assert.deepEqual(copyMachine([true, true, null], 1), [[true, true, null]], "<code>copyMachine([true, true, null], 1)</code> should return <code>[[true, true, null]]</code>.");
assert.deepEqual(copyMachine(['it works'], 3), [['it works'], ['it works'], ['it works']], "<code>copyMachine(['it works'], 3)</code> should return <code>[['it works'], ['it works'], ['it works']]</code>.");
assert.notStrictEqual(copyMachine.toString().search(/\.\.\./), -1, "The <code>copyMachine</code> function should utilize the <code>...</code> syntax.");
no-stack-dub-sack commented 7 years ago

Check for the presence of an element with indexOf()

Instructions

Since arrays can be changed, or mutated, at any time, there's no guarantee about where a particular piece of data will be on a given array, or if that element even still exists. Luckily, JavaScript provides us with another built-in method, indexOf(), that allows us to quickly and easily check for the presence of an element on an array. indexOf() takes an element as a parameter, and when called, it returns the position, or index, of that element, or -1 if the element does not exist on the array.

For example:

let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
fruits.indexOf('dates') // returns -1
fruits.indexOf('oranges') // returns 2
fruits.indexOf('pears') // returns 1, the first index at which the element exists

Instructions

indexOf() can be incredibly useful for quickly checking for the presence of an element on an array. We have defined a function, quickCheck, that takes an array and an element as arguments. Modify the function using indexOf() so that it returns true if the passed element exists on the array, and false if it does not.

Challenge Seed

function quickCheck(arr, elem) {
    // change code below this line

    return elem;
}

quickCheck(['squash', 'onions', 'shallots'], 'mushrooms');

Challenge Solution

function quickCheck(arr, elem) {
    if (arr.indexOf(elem) !== -1) {
    return true
    } else {
    return false;
    }
}

Tests

assert.strictEqual(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'), false, "<code>quickCheck(['squash', 'onions', 'shallots'], 'mushrooms')</code> should return <code>false</code>.");
assert.strictEqual(quickCheck(['squash', 'onions', 'shallots'], 'onions'), true, "<code>quickCheck(['squash', 'onions', 'shallots'], 'onions')</code> should return <code>true</code>.");
assert.strictEqual(quickCheck([3, 5, 9, 125, 45, 2], 125), true, "<code>quickCheck([3, 5, 9, 125, 45, 2], 125)</code> should return <code>true</code>.");
assert.strictEqual(quickCheck([true, false, false], undefined), false, "<code>quickCheck([true, false, false], undefined)</code> should return <code>false</code>.");
assert.notStrictEqual(quickCheck.toString().search(/\.indexOf\(/), -1, "The <code>quickCheck</code> function should utilize the <code>indexOf() method.</code>");
no-stack-dub-sack commented 7 years ago

Iterate through all the items in an array

Instructions

Sometimes when working with arrays, it is very handy to be able to iterate through each item to find one or more elements that we might need, or to manipulate an array based on which data items meet a certain set of requirements. JavaScript offers several built in methods that each iterate over arrays in slightly different ways to achieve different results (such as every(), forEach(), map(), etc.), however the technique which is most flexible and offers us the greatest amount of control is a simple for loop.

For example:

function greaterThanTen(arr) {
    let newArr = [];
    for (let i = 0; i < arr.length; i++) {
    if (arr[i] > 10) {
        newArr.push(arr[i]);
    }
    }
    return newArr
}

greaterThanTen([2, 12, 8, 14, 80, 0, 1]);
// returns [12, 14, 80]

Using a for loop, this function iterates through and accesses each element of the array, and subjects it to a simple test that we have created. In this way, we have easily and programmatically determined which data items are greater than 10, and returned a new array containing those items.

Instructions

We have defined a function, filteredArray, which takes arr, a nested array, and elem as arguments, and returns a new array. elem represents an element that may or may not be present on one or more of the arrays nested within arr. Modify the function, using a for loop, to return a filtered version of the passed array such that any array nested within arr containing elem has been removed.

Challenge Seed

function filteredArray(arr, num) {
    newArr = [];
    // change code below this line

    // change code above this line
    return newArr;
}

filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3);

Challenge Solution

function filteredArray(arr, num) {
    let newArr = [];
    for (let i = 0; i < arr.length; i++) {
    if (arr[i].indexOf(num) === -1) {
            newArr.push(arr[i]);
    }
    }
    return newArr;
}

Tests

assert.deepEqual(filteredArray([ [10, 8, 3], [14, 6, 23], [3, 18, 6] ], 18), [[10, 8, 3], [14, 6, 23]], "<code>filteredArray([[10, 8, 3], [14, 6, 23], [3, 18, 6]], 18)</code> should return <code>[[10, 8, 3], [14, 6, 23]]</code>");
assert.deepEqual(filteredArray([ ['trumpets', 2], ['flutes', 4], ['saxaphones', 2] ], 2), [['flutes', 4]], "<code>filteredArray([['trumpets', 2], ['flutes', 4], ['saxaphones'], 2], 2)</code> should return <code>[['flutes', 4]]</code>");
assert.deepEqual(filteredArray([['amy', 'beth', 'sam'], ['dave', 'sean', 'peter']], 'peter'), [['amy', 'beth', 'sam']], "<code>filteredArray([['amy', 'beth', 'sam'], ['dave', 'sean', 'peter']], 'peter')</code> should return [['amy', 'beth', 'sam']].");
assert.deepEqual(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3), [], "<code>filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3)</code> should return <code>[]</code>.");
assert.notStrictEqual(filteredArray.toString().search(/for/), -1, "The <code>filteredArray</code> function should utilize a <code>for</code> loop.");
no-stack-dub-sack commented 7 years ago

Create complex nested arrays

Instructions

One of the most powerful features when thinking of arrays as data structures, is that arrays can contain, or even be completely made up of other arrays. We have seen arrays that contain arrays in previous challenges, but fairly simple ones. However, arrays can contain an infinite depth of arrays that can contain other arrays, each with their own arbitrary levels of depth, and so on. In this way, an array can very quickly become very complex data structure, Consider the following example:

let nestedArray = [ // top, or first level - the outer most array
    ['deep'], // an array within an array, 2 levels of depth
    [ 
        ['deeper'], ['deeper'] // 2 arrays nested 3 levels deep
    ], 
    [ 
        [ 
            ['deepest'], ['deepest'] // 2 arrays nested 4 levels deep 
        ], 
        [ 
            [
                ['deepest-est?'] // an array nested 5 levels deep
            ] 
        ]
    ], 
];

While this example may seem convoluted, this level of complexity is not unheard of, or even unusual, when dealing with large amounts of data.

However, we can still very easily access the deepest levels of an array this complex with bracket notation:

console.log(nestedArray[2][1][0][0][0]);
// logs 'deepest-est?'

And now that we know where that piece of data is, we can reset it if we need to:

nestedArray[2][1][0][0][0] = 'deeper still';
console.log(nestedArray[2][1][0][0][0]);
// now logs 'deeper still'

Instructions

We have defined a variable, myNestedArray, set equal to an array. Modify myNestedArray, using any combination of strings, numbers, and booleans for data elements, so that it has exactly three levels of depth (remember, the outer-most array is level 1).

Challenge Seed

let myNestedArray = [

    // change code here

];

Challenge Solution

let myNestedArray = [
    [
        1, 2, 3, 3, 5, 6, [true, false, false, 12]
    ]
];

Tests

assert.strictEqual((function(arr) { let flattened = (function flatten(arr) { const flat = [].concat(...arr); return flat.some (Array.isArray) ? flatten(flat) : flat; })(arr); for (let i = 0; i < flattened.length; i++) { if ( typeof flattened[i] !== 'number' && typeof flattened[i] !== 'string' && typeof flattened[i] !== 'boolean') { return false } } return true })(myNestedArray), true, "<code>myNestedArray</code> should contain only numbers, booleans, and strings as data elements.");
assert((function(arr) { for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) {for (let j = 0; j < arr[i].length; j++) { if (Array.isArray(arr[i][j])) { return true } } } } })(myNestedArray) === true && (function(arr) { for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr[i].length; j++) { for (let k = 0; k < arr[i][j].length; k++) { if ( Array.isArray(arr[i][j][k]) ) { return false } } } } })(myNestedArray) === undefined, "<code>myNestedArray</code> should have exactly 3 levels of depth.");
no-stack-dub-sack commented 7 years ago

Combining arrays with spread syntax

Instructions

Another huge advantage of the spread syntax, is the ability to combine arrays, or to insert all the elements of one array into another, at any index. With more traditional syntaxes, we can concatenate arrays, but this only allows us to combine arrays at the end of one, and at the start of another. Spread syntax makes the following operation extremely simple:

let thisArray = ['sage', 'rosemary', 'parsely', 'thyme'];

let thatArray = ['basil', 'cilantro', ...thisArray, 'corriander'];
// thatArray now equals ['basil', 'cilantro', 'sage', 'rosemary', 'parsely', 'thyme', 'corriander']

Using spread syntax, we have just achieved an operation that would have been more more complex and more verbose had we used traditional methods.

Instructions

We have defined a function spreadOut that returns the variable sentence, modify the function using the spread syntax so that it returns the array ['learning', 'to', 'code', 'is', 'fun'].

Challenge Seed

function spreadOut() {
    let fragment = ['to', 'code'];
    let sentence = 'change code here'
    return sentence;
}

spreadOut();

Challenge Solution

function spreadOut() {
    let fragment = ['to', 'code'];
    let sentence = ['learning', ...fragment, 'is', 'fun'];
    return sentence;
}

Tests

assert.deepEqual(spreadOut(), ['learning', 'to', 'code', 'is', 'fun'], "<code>spreadOut</code> should return <code>['learning', 'to', 'code', 'is', 'fun']</code>.");
assert.notStrictEqual(spreadOut.toString().search(/\.\.\./), -1, "The <code>spreadOut</code> function should utilize the spread syntax.");
no-stack-dub-sack commented 7 years ago

@QuincyLarson, @bonham000 Ok! These array challenges are now done, I've just posted mine and all challenges are linked to their titles in the OP. Really looking forward to checking all this stuff out in beta!

QuincyLarson commented 7 years ago

@no-stack-dub-sack awesome work! I've been reading through these, and they look great. I'll start importing them into the seed file.

@smileytechguy I'm going to go ahead and close this issue and if you want to create a "Insert elements with spread syntax" later, we can add this later.

no-stack-dub-sack commented 7 years ago

@QuincyLarson I went ahead and added that challenge because I wasn't sure if we were waiting on this, I'm sure there's improvements that can be made though if @smileytechguy wants to take a look and help QA these! I changed the title I initially had to a more appropriate "Combine arrays with spread syntax"

QuincyLarson commented 7 years ago

@no-stack-dub-sack awesome! I didn't see that. OK - we're good to go then.

@smileytechguy there will be tons of opportunities to improve and expand our curriculum once we get these live.

ncovercash commented 7 years ago

These look pretty good!

LudwigJedde commented 6 years ago

Add items to an array with push() and unshift()

Description:

An array's length, like the data types it can contain, is not fixed. Arrays can be defined with a length of any number of elements, and elements can be added or removed over time. In this challenge, we will look at two methods with which we can programmatically modify an array: Array.push() and Array.unshift().

Both methods take one or more elements as parameters and add those elements to the array the method is being called on; the push() method adds elements to the end of an array, and unshift() adds elements to the beginning. Consider the following:

let twentyThree = 'XXIII';
let romanNumerals = ['XXI', 'XXII'];

romanNumerals.unshift('XIX', 'XX'); 
// now equals ['XIX', 'XX', 'XXI', 'XXII']
romanNumerals.push(twentyThree); 
// now equals ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']

Notice that we can also pass variables, which allows us even greater flexibility in dynamically modifying our array's data.

Instructions:

We have defined a function, mixedNumbers, which we are passing an array as an argument. Modify the function by using push() and shift() to add 'I', 2, 'three', to the beginning of the array and 7, 'VIII', '9' to the end so that the returned array contains representations of the numbers 1-9 in order.

Challenge Seed:

function mixedNumbers(arr) {
    // change code below this line

    // change code above this line
    return arr;
}

// do not change code below this line
mixedNumbers(['IV', 5, 'six'])

Challenge Solution

function mixedNumbers(arr) {
    arr.push(7, 'VIII', '9');
    arr.unshift('I', 2, 'three');
    return arr;
}

Tests:

assert.deepEqual(mixedNumbers(['IV', 5, 'six']), ['I', 2, 'three', 'IV', 5, 'six', 7, 'VIII', '9'], "<code>mixedNumbers(['IV', 5, 'six'])</code> should now return <code>['I', 2, 'three', 'IV', 5, 'six', 7, 'VIII', '9']</code>");
assert.notStrictEqual(mixedNumbers.toString().search(/\.push\(/), -1, "The <code>mixedNumbers</code> function should utilize the <code>push()</code> method."); 
assert.notStrictEqual(mixedNumbers.toString().search(/\.unshift\(/), -1, "The <code>mixedNumbers</code> function should utilize the <code>unshift()</code> method."); 

you have to put this on to validate the exercise 9 and not '9' in arr.push

function mixedNumbers(arr) {

arr.push(7, 'VIII', 9 );
arr.unshift('I', 2, 'three');
return arr;
QuincyLarson commented 6 years ago

@LudwigJedde Thanks for catching this. Could you create a GitHub issue on github.com/freecodecamp/freecodecamp instead? This repo is archived. Then we can tackle fixing this.