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! While you're at it, check out some resources Treehouse students have shared here.

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

JavaScript

How 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

This 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

Thanks 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

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

Also, you can select one of my replies as best answer, if it's the best answer for this question thread. :)

Thank 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

In other words, I need to get the original date array each year came from, and replace the year with it

Could 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?

Sure, give me a minute

<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
  }
}
});
};

Hmm...

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.

https://jsfiddle.net/1v3dxt6q/

Impressive! 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?

First, 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. :)

https://momentjs.com/

Thanks dude

One more question Joseph, when I test your sorting function, the console produces the error "a.diff() is not a function"

I 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.

Sorry, 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);
  }
}
});
};

Make 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>

Sorry, 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>

I 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

As an aside, you keep adding answers instead of comments. consider using the comment feature instead of commenting through answers.