Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Jackson Monk
4,527 PointsHow can I do this?
I know javascript has a replace method for strings and regular expressions, but I need to replace a number in an array with another array. Is this possible? If so, I am open to suggestions.
12 Answers

Joseph Wasden
20,406 PointsThis seems to work.
let unchangedArray = [0, 1, 2]
function replaceNumberInArray(currentArray, indexOfNumberToReplaceInCurrentArray, replacementArray) {
let result = currentArray.map(function(element, index) {
if (index == indexOfNumberToReplaceInCurrentArray) {
return element = replacementArray;
} else {
return element;
}
});
return result;
}
replaceNumberInArray(unchangedArray, 0, [10, 20, 30]); // returns [ [10, 20, 30], 1, 2 ]
Our replaceNumberInArray() function iterates over a supplied array, and once it finds the index you specified, it replaces that index value with whatever replacement array you specified. It then returns the new array.
Map is a method you can call off of arrays. It iterates over all the values in the array, performs some kind of logic (that generally includes some kind of transformation of the current iteration's value), and then returns a new array. The block of the function() passed as an argument of map() is where logic is specified that will be executed for each value iteration. the arguments of that function(element, index) give you access to a reference of the element being iterated over (in this case, the element) and the index of that element in the array (in this case, index).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Jackson Monk
4,527 PointsThanks so much Joseph you're a lifesaver. Will definitely be using moment.js library in the future for dates. Do you know of any courses that go into depth on this library? I'd love to learn more about it

Joseph Wasden
20,406 PointsI don't know of any courses, no, but just ask around here, check the docs, or give it a good google. :)

Joseph Wasden
20,406 PointsAlso, you can select one of my replies as best answer, if it's the best answer for this question thread. :)

Jackson Monk
4,527 PointsThank you Joseph, I will try that but first I want to make sure we're more clear on what I'm talking about, because I was pretty vague about the question. I am trying to sort dates. Each date is in an array, all inside another array. I want to sort them by year first, then replace the sorted year with its corresponding date. Voila. Dates sorted. My problem is I need to replace each year with its date in the sorted array, and I'm not exactly sure how

Jackson Monk
4,527 PointsIn other words, I need to get the original date array each year came from, and replace the year with it

Joseph Wasden
20,406 PointsCould you share a sample of the data you're working with, or a similar example with dummy data? Enough at least to see how the data is structured?

Jackson Monk
4,527 PointsSure, give me a minute

Jackson Monk
4,527 Points<html>
<head></head>
<body>
<h1>Sorting Dates</h1>
<h3>Input dates in MM/DD/YYYY and they will be sorted in chronological order. Click Enter to enter each date and Sort when you want to sort your dates</h3>
<input type = text> <button>Enter</button> <button>Sort</button>
<script src = cryena.js></script>
</body>
</html>
window.onload = function() {
let input = document.getElementsByTagName('input')[0];
let buttons = document.getElementsByTagName('button');
let storagearr = [];
let datearr = [];
let date;
let split;
let years = [];
let months = [];
let days = [];
let sortedYears;
let sortedMonths;
let sortedDays;
buttons[0].addEventListener('click', () => {
date = input.value;
split = date.split('/');
if (!split[1]) {
alert('Please enter a valid date in the following format: MM/DD/YYYY | Example: 05/19/2018');
}
else if (isNaN(split[0]) || isNaN(split[1]) || isNaN(split[2])) {
alert('You must input numbers as your dates');
}
else if (split[0] < 1 || split[0] > 12 || split[1] < 1 || split[1] > 31) {
alert('Your month or day is invalid. (Program accepts days up to 31, even for months that do not have 31 days)');
}
else if (split[2].length !== 4) {
alert('Year format must be YYYY');
}
else {
for (let a = 0; a < split.length; a ++) {
split[a] = parseInt(split[a]);
}
datearr.push(split);
}
});
buttons[1].addEventListener('click', () => {
if (!datearr[0]) {
alert('You must input at least one date');
}
else {
for (let b = 0; b < datearr.length; b ++) {
months.push(datearr[b][0]);
days.push(datearr[b][1]);
years.push(datearr[b][2]);
}
sortedYears = years.sort(function() {
return a - b;
}); // want to replace sorted years with their corresponding dates
for (let c = 0; c < sortedYears.length; c ++) {
if (sortedYears[c - 1] == sortedYears[c] || sortedYears[c + 1] == sortedYears[c]) {
secondLevel();
}
}
function secondLevel() {
sortedMonths = months.sort(function() {
return a - b;
}); // want to replace the sorted months with their corresponding years
for (let d = 0; d < sortedMonths.length; d ++) {
if (sortedMonths[d - 1] == sortedMonths[d] || sortedMonths[d + 1] == sortedMonths[d]) {
thirdLevel();
}
}
}
function thirdLevel() {
sortedDays = days.sort(function() {
return a - b;
}); // want to replace the sorted days with their corresponding months
}
}
});
};

Joseph Wasden
20,406 PointsHmm...
I'm not sure I would go that route to sort dates. If you're not constrained to that approach, I'd consider looking into a library like moment.js to help you manage dates. I drew up a little jsfiddle to demonstrate how I would sort dates using Array.prototype.sort() and Moment.js.

Jackson Monk
4,527 PointsImpressive! Now I'm no JavaScript expert, so I do have a couple questions. First, how does the function you sorted the dates with work? And second, do you mind explaining what the value of newDate is and what it does?

Joseph Wasden
20,406 PointsFirst, how does the function you sorted the dates with work?
The way it was sorted used the sort method. sort can be called on any javascript array. here's the code that does the heavy lifing.
sortedDates = enteredDates.sort(sortComparator);
While Array.sort() does have a default method for sorting (something about the order of String unicode characters), it is generally most useful when you can define what values in the array you want to compare and how. Javascript doesn't intuitively know you want to compare dates, or what kinds of differences you are looking for. Defining how you want to compare values is generally referred to as a comparator or comparable. You can see some examples of comparators in the MDN docs for the sort method. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Using those examples as inspiration, I wrote this comparator function.
var sortComparator = function(a,b){
if(a.diff(b) > 0) return 1;
if(a.diff(b) < 0) return -1;
return 0;
}
The arguments a and b represent any given two array values that will be compared. How did I know this? The sort documentation and a healthy guess and check. :) The if statements in sortComparator are a bit trickier. they are using the diff method from the moment.js library (which I highly encourage you to check out if you are working with dates and times in js. It's made a few of my projects much easier.) Also, all the dates that are in my array have been converted to Moment objects, which is why i can check them using diff this way. if the difference between a and b is positive, then a is more recent than b. we tell the sort method this by returning 1. If the difference between a and b is negative, then b is more recent than a. we tell the sort method this by returning -1. if neither of these are true, then they are the same time. We tell the sort method this by returning 0.
Now that I have the sortComparator function, I can call the sort method off the array I want to sort, and pass it sortComparator so it knows how I want it to sort the array. Sort does the hard work behind the scenes, and sorts our array as we described that it should.
And second, do you mind explaining what the value of newDate is and what it does?
here's that bit of code.
let newDate = moment(dateToAdd.value, "MM-DD-YYYY");
moment() is how you covert your date string into into a Moment object. it takes a date string, and a declaration of the format of that date string.
dataToAdd.value is the value of the text field input, in other words, our date string.
"MM-DD-YYYY" is lettting moment.js know what format the date string is in, so that it can correctly convert the date to a momentjs object.
This conversion to a Moment object is a necessary step, since sortComparator is using a moment.js diff method to compare the dates as moment objects. There's definitely a way to compare using just native javascript dates, but this was just a faster way forward for me.
Hope that was all more clarifying than confusing. :)

Jackson Monk
4,527 PointsThanks dude

Jackson Monk
4,527 PointsOne more question Joseph, when I test your sorting function, the console produces the error "a.diff() is not a function"

Joseph Wasden
20,406 PointsI could ask a bunch of questions, but seeing your code would be fastest to trouble shoot why you're getting an error. Maybe share how your using it here or some other way?
My guess is that the objects in the array you are trying to sort haven't been converted to Moment objects.

Jackson Monk
4,527 PointsSorry, completely forgot to post my code lol. Here it is:
window.onload = function() {
let input = document.getElementsByTagName('input')[0];
let buttons = document.getElementsByTagName('button');
let datearr = [];
let date;
let split;
let sortedDates;
let sorter = function(a, b) {
if(a.diff(b) > 0) return 1;
if(a.diff(b) < 0) return -1;
return 0;
}
buttons[0].addEventListener('click', () => {
date = input.value;
split = moment(date, "MM-DD-YYYY");
datearr.push(" " + split);
alert("Date Added");
input.value = '';
});
buttons[1].addEventListener('click', () => {
if (!datearr[0]) {
alert('You must input at least one date');
}
else {
sortedDates = datearr.sort(sorter);
if (!sortedDates[1]) {
document.write("Here is your date: " + sortedDates);
}
else {
document.write("Here are your dates sorted chronologically: " + sortedDates);
}
}
});
};

Joseph Wasden
20,406 PointsMake sure you include a reference to momentjs in your HTML file.
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/locale/af.js"></script>

Jackson Monk
4,527 PointsSorry, here is html code too:
<html>
<head></head>
<body>
<h1>Sorting Dates</h1>
<h3>Input dates in MM/DD/YYYY and they will be sorted in chronological order. Click Enter to enter each date and Sort when you want to sort your dates</h3>
<input type = text> <button>Enter</button> <button>Sort</button>
<script src = cryena.js></script>
<script src = moment.js></script>
</body>
</html>

Jackson Monk
4,527 PointsI actually copied all the code out of one of the files in the momentjs library and pasted it in another file in my workspace named moment.js and linked it in to my html file

Joseph Wasden
20,406 PointsAs an aside, you keep adding answers instead of comments. consider using the comment feature instead of commenting through answers.