Chapter 4 - Exercises

Yes, you’ve got it, @JustinP!  :+1:

The function is working on myArray (not really its own version). You pass myArray in as the argument here:

console.log(reverseArrayInPlace(myArray));

which becomes the parameter you have decided to call arrayToReverse. But it’s still exactly the same array, and you could have kept the name the same:

function reverseArrayInPlace(myArray) {...}
/* would also work as long as you also change all references
   from arrayToReverse to myArray in the function body */

So whatever you decide to name the array for the purposes of manipulating it within the function (as a parameter), what you are returning to the function call and logging to the console is what is stored in the variable myArray, and which is why both your console.logs output identical arrays, because they are the same array value.

You can further prove to yourself that the function is actually modifying myArray in place by doing the following:

  • remove: return arrayToReverse;
    remove the console.log from the function call so you just have:
    reverseArrayInPlace(myArray);
  • Run the program and you will notice that myArray has still changed even though the function isn’t returning any value. Can you see why?

Great work and perseverance! :smiley:

2 Likes

Great stuff!

I was particularly interested in your unique approach and solution for Sum of a Range. Very innovative and creative! :ok_hand:

Don’t be disheartened, @Zoltan, this particular exercise is very difficult. The fact that you kept on going and didn’t just give up is just as valuable as getting the right solution on your own! The main objective here is to “wrestle” with the problem yourself first, then when you check with the hints, model answers or other students’ solutions, you should spend time working out why the code is written as it is, what it’s actually doing.

Don’t worry about the bit about testing to see which one runs faster. I spent hours trying get some meaningful results using:

console.time();
/* and */
console.timeEnd();

But to be honest, I didn’t really get anything definitive. You can use these functions to carry out your own tests if you like, but to be honest, I think your time is better spent continuing with other things. I know it isn’t very clear, but we don’t actually expect students to do this bit as part of the course. But don’t let us stop you if you’re interested!
Rather than the speed issue, I think it is worth thinking about the other aspect of this additional question:
What type(s) of use case(s) can you see each variant being more/less suited to?
i.e. Which would you prefer to use, and when, and for what?
We don’t expect you to post answers to these questions here in the forum, but by all means share with us any thoughts or further questions you may have, and we’ll take a look.

2 Likes

Exercise.

       var range = function (start, end){
         var arr = [];
            cnt = start;
         while (cnt <= end) {
           arr.push(cnt);
              cnt++;
         }
         return arr;
       };

       var sum = function (arr) {
       var total = 0;
            for (let i=0; i<arr.length; i++) {
              total = total + arr [i];

          }
          return total;
        };

       console.log(sum(range(1, 10)));
1 Like

I honestly don’t yet see the possible use cases for many little programs we have had to write. I’m so new to this space, that I don’t really have an understanding of how I’ll be able to use all these things I learn here. I would like to work in this space, but I don’t know if I’ll ever get enough knowledge to be able to compete with people whom have been studying programming in colleges.
For now all we have done during this course, is a big mess in my head, and I have no idea if I’ll ever get anywhere with it. I keep on with the course, because I’m hoping that one day all will just click in and I’ll see the full picture.

Thank you for your input regarding the exercises!

Zoltan

1 Like

Hi @dAnijboned!

I’m going to give you separate feedback on both exercises in separate posts.

The Sum of a Range

Again, you’ve come up with a very unique and innovative solution. This was a really interesting piece of work to review :slightly_smiling_face:

In the second part, where you introduce the step variable, when you call and log createRangeArrayStep you should also include the same sumArrayValues function that you used in the first part to sum the range:

console.log(sumArrayValues(createRangeArrayStep(1, 10, 2)));
console.log(sumArrayValues(createRangeArrayStep(5, 2, -1)));

With your code as it is at the moment, you log both range and sum for the first part, but for the second part you only log the array of the range to the console (without its sum).

Generally speaking:

  • for...of should be used to iterate over arrays (where the property names (or keys) are the index values i.e. integers);
  • for...in should be used to iterate over objects whose property keys are strings, and therefore in no specific numeric order.

If you want to explore this further and find out why, then take a look at these MDN web docs:


If you read more about these types of for loops, you will see that you can write your for loop even more concisely:

for(let i of inputArray) {
   retval += i;
}

The final point to mention is that you’ve dealt effectively with the issue of reverse stepping :+1: But it fails to handle function calls when the step argument is undefined, such as:

console.log(range(1, 10));
console.log(sum(range(1, 10)));
// or
console.log(range(5, 2));
console.log(sum(range(5, 2)));

The exercise tells us that the step parameter is optional, and where it is not given, the step will either be 1 or -1 depending on whether it is a reverse range or not.

Hint You can avoid adding more if...else statements, by using a ternary operator to add this functionality; and you can do it all very concisely in the function header…

1 Like

You’ve nailed both variations of Reversing an Array !
Fantastic work, @dAnijboned!
I am simply blown away by your use of…

…in your reverseArrayV2:star_struck:

I know it isn’t very clear, but we don’t actually expect students to do the speed analysis part of this question. But we certainly don’t stop anyone!

I actually tested this when I originally did this exercise, and to be honest, I didn’t actually find any significant difference in the speed. If anything, my version of the pure function reverseArray may actually have been slightly faster.

If you’re interested, take a look at this post which summarises my analysis and also quotes from other students’ comments on this.

You’re making fantastic progress, Daniel!
Really, well done! :smiley:

1 Like

Hi @jon_m !

I’ve added a default value for the step parameter:

function createRangeArrayStep(start, end, step = 1)

Sorry, I sometimes go too fast through the exercises and I don’t read some part of them :sweat_smile:

Thanks for the for…of / for…in explanation!

1 Like

Hi @jon_m !

I’ve created a test array:

var testArray = createRangeArray(0, 1000000);

And then timed the execution of reverseArray and reverseArrayInPlace:

reverseArray

var t0 = performance.now();
reverseArray(testArray);
var t1 = performance.now();
console.log("Call to reverseArray took " + (t1 - t0) + " milliseconds.");

Call to reverseArray took 59.089999995194376 milliseconds.

reverseArrayInPlace

var t0 = performance.now();

reverseArrayInPlace(testArray);

var t1 = performance.now();
console.log("Call to reverseArrayInPlace took " + (t1 - t0) + " milliseconds.");

Call to reverseArrayInPlace took 12.229999992996454 milliseconds.

With this numbers, it seemed that the “in place” version was faster (for the implementation I did at least).

1 Like

Hi Jon,

I’ve finished the range function:

 function range(start, end)
  {
      let result = [];
      result.push(start);
      for (let n = 1; n < end - start + 1; n++)
      {
          result.push(start + n);
      }
      return result;
  }
  console.log(range(1, 10));
1 Like

Here’s my attempt for the bonus assignment with step argument:

  function stepArray(start, end, step = 1)
  {
      let result = [];
      for (let n = 0; n < end - start + 1; n += step)
      {
          result.push(start + n);
      }
      return result;
  }
  
  console.log(range(stepArray(1, 10, 2)));
1 Like

At the time, I truly did reach that saturation point haha
It was truly two minuses that merged so I’ll pay more attention to proper formatting. I agree that your statement is more economical as all languages should be. Here’s, hopefully, the final fix:

    var fruits = ["1_apple", "2_orange", "3_lemon", "4_mango", "5_durian"];

    function reverseArray(myArray) {
        var newArray = [];
         newArrayIndex = myArray.length;
         for (var i = 0; i < myArray.length; i++) {
             newArray.unshift(myArray[i]);
        }
      return newArray;
    }
    console.log(fruits);
     // Inversion
    console.log(reverseArray(fruits));
1 Like

Hey @AndyP!

That’s a good start to the exercise :+1:

Are you going to try to build on it, and introduce functionality to first handle reverse ranges, and then to add the 3rd step parameter? Take your time, these exercises are a real challenge. If you need some help, I would suggest these possible approaches (depending on what you’ve already tried yourself)…

  1. Have a look at the hints (which you can display in the online course book by clicking below the exercise instructions).
  2. If you still don’t get it, have a look at other students’ posts here, with their attempts, solutions, and the help, comments and feedback posted as replies.
  3. Look at the model answer given in the course book. Try to work out how it achieves the desired result, and then maybe think about how you would have done it, which could well be different.
  4. If you reach saturation point…leave it…but come back to it after you’ve progressed a bit more with the course, and done some more of your own practice and research. You may well find it much more manageable then :slightly_smiling_face:
1 Like

Hi @Zoltan,

That’s perfectly normal when you start out. Judging by the quality of the code for the dynamic list you put together, and the analytical thought you put into making it more streamlined, you’ve already learnt and absorbed a lot more than you realise.

Don’t worry about that additional part to the Reversing an Array exercise. To be honest, I think asking a relatively new programmer to actively think now about use cases for programs like that, is not that productive and a bit unnatural. What we want to be aiming for is building up exposure to lots of different possible coding scenarios and bite-size solutions (like these many little programs you mention) so that when we finally have a real-world project we need or want to build (in other words a real use case), then hopefully we will then see how certain chunks of code we’ve had exposure to in the past can now be used to help solve the specific problems and challenges of our project — kind of like a toolbox we’ve gradually been adding to and building up while studying.

Rather than aquiring knowledge, I actually think that aquiring the tools and developing the skills needed (such as logical and analytical thinking, the ability to carry out focussed and effective research, and to find effective and innovative solutions) likely plays a bigger role in whether someone is successful in this space.

It often feels like that, because you’ve absorbed an awful lot in a very short space of time, but your brain just needs time to catch up and get its filing system organised. That will happen in its own time, and not overnight. Just be patient, and accept that the frustrating feeling of things being a mess, is all part of the natural learning process.

Try to stay positive, don’t be too hard on yourself, and try to enjoy the journey as much as you can! :slightly_smiling_face:

4 Likes

Nice! :ok_hand:
That handles a default incremental step… but we also need to handle a default negative (or reverse) step. For example, when our function call is:

Only adding step = 1 won’t handle that. You need to expand it by using a ternary operator…

1 Like

Hi @jon_m

Sorry, I don’t know if I’m missing something here :sweat_smile:

The step functionality is implemented in the createRangeArrayStep version of the createRangeArray function.

The code that handles the reverse step is inside the for loop:

 if(reverseOrder) {
            if(i < end)
              break;
          } else if (i > end){
            break;
          }
console.log(createRangeArrayStep(5, 2, -1));
[5, 4, 3, 2]

Yes, your code handles the reverse step, but only if you have a step parameter with a minus value. As you indicate here (this works perfectly):

However, because your default step parameter for the entire function is step = 1 this won’t handle a function call of:

console.log(createRangeArrayStep(5, 2));   // undefined step parameter
// This enters an infinite loop and doesn't output [5, 4, 3, 2]

For your function to handle that, it needs to be able to change the default step from 1 to -1. We need conditional execution within the default parameter to handle that. If you make your default step parameter for the whole function as follows, it will work for both incremental and reverse steps (i.e. defaults of 1 or -1)

function createRangeArrayStep(start, end, step = start < end ? 1 : -1)

Try it out, and let me know if you still don’t get it :+1:

1 Like

Oh F**k! Now I see it :joy: Thanks!

1 Like

Great, @Ondrej.S!

Now, you can run both functions together as follows. You only need to make one amendment to your original sum function (see the comment).

function range(start, end) {
   let result = [];
   result.push(start);
   for (let n = 1; n < end - start + 1; n++) {
      result.push(start + n);
   }
   return result;
}

function sum(rangeArray) {
   var total = 0;
   for(let i = 0; i < rangeArray.length; i++) {
      total += rangeArray[i];
   }
   return total;      // CHANGED FROM console.log(total)
}

console.log(range(1, 10));          // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(sum(range(1, 10)));     // => 55
1 Like

Excellent progress, @Ondrej.S! :smiley:

Again, you can now run this function together with sum as follows.
Note: You need to pass the function as an argument to sumNOTrange !

function stepArray(start, end, step = 1) {
   let result = [];
   for (let n = 0; n < end - start + 1; n += step) {
      result.push(start + n);
   }
   return result;
}

function sum(rangeArray) {
   var total = 0;
   for (let i = 0; i < rangeArray.length; i++) {
      total += rangeArray[i];
   }
   return total;      // CHANGED FROM  console.log(total)
}

console.log(stepArray(1, 10, 2));          // => [1, 3, 5, 7, 9]
console.log(sum(stepArray(1, 10, 2)));     // => 25

// Still works when the step parameter is undefined
console.log(stepArray(1, 10));             // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(sum(stepArray(1, 10)));        // => 55

When you feel ready (leave it for a bit if you feel saturated, and then come back to it) you can continue working on your stepArray function to add functionality for reverse ranges, with an optional negative step parameter.

1 Like

Thank you Jon!

I have moved onto C++ course now, hopefully I’ll be able to apply some of the knowledge there.
I thought we will go deeper into JavaScript, as we only have done 20% of Eloquent JavaScript. The sudden dropping of JS and moving onto C++ is a bit confusing. But I guess I’ll just have to go with the flow of the course.