Chapter 4 - Exercises

//Ex.1 The sum of a range
    numbers=[];
    function range(start,end,step){
      numbers.length=0;
      if (step==undefined){step =1;};
      if (step<0){
        for(i=start;i>=end;i=i+step){
         numbers.push(i);
       }

     }else{
        for(i=start;i<=end;i=i+step){
         numbers.push(i);
       }
     }return numbers;
    }

    function sum(array){
      arraySum=0;
      for (i=0;i<array.length;i++){
        arraySum=arraySum+array[i];
      } return arraySum;
    }
//Ex.2 Reversing an array
    numbers1=[1,2,3];
    console.log(numbers1);

    function reverseArray(array){
      reversedArray=[];
      for (i=0;i<array.length;i++){
        reversedArray[i]=array[array.length-1-i];
      }return reversedArray;
    }
    console.log(reverseArray(numbers1));

    numbers2=[4,5,6];
    console.log(numbers2);

    function reverseArrayInPlace(array){
      for (i=0;i<Math.ceil(array.length/2);i++){
        temp=array[i];
        array[i]=array[array.length-1-i];
        array[array.length-1-i]=temp;
      }return array;
    }
1 Like

Reversing an Array

function reverseArray(arrayToReverse){
var newArray = [""];
var lengthOfArray = (arrayToReverse.length)-1;
var counter = lengthOfArray;
var newArrayCounter = 0;
while (counter >= 0){
console.log("counter "+ counter);
newArray[newArrayCounter] = arrayToReverse[counter];
counter --;
newArrayCounter++;
}
return newArray
}

var myArray = [“Lions”, “Tigers”, “Bears”, “Walrus”, “Elephant”];

var animals = reverseArray(myArray);

console.log(animals);

1 Like

Hi @CryptoVic!
Sorry for the delay in giving you some feedback.

In order for me to check your code for this first exercise, I need to also see your function which produces the array in the first place i.e.the function which generates an array based on start, end and step parameters, so we have the functionality to be able to sum different array variations.
Without seeing this initial function, I can’t guage how much of the task you’ve actually understood. So if what I’m asking for doesn’t make sense, just let me know and we can discuss further! :smiley:

In terms of your sum function, it’s looking good, but have another think about the position of  return accumulator; within the function. At the moment it’s going to cause your for loop to be exited on the first iteration, only returning the number at index 0, rather than the sum.

I’m going to have a look at your second exercise now, but I just wanted to get back to you on the first exercise first.

Hi @JustinP!

Sorry for the delay in replying.
Did you forget to add the code for Reversing an Array? :wink:
If you send it again I’ll review it for you.
I can see you’ve sent the code for the 2nd exercise - I’ll get to that in a bit.

Hi again, @CryptoVic!

Great effort with Reversing an Array !
It nearly works.
You just have 2 problems with the for loop:

  1. Your condition causes the loop to be exited before index 0 has been “pushed” to the end of the array, and not immediately after. See if you can work out what the problem is and how to solve it, then repost your code here.
  2. I’m not sure if it’s just a formatting error when posting your code, but your decrement operator is a dash rather than 2 minus signs. This throws an error.

Concerning formatting, I’m not sure if you know, but before you enter your code to post it here in the forum, click on the </> icon in the menu at the top of the text editor. That will give you 2 sets of 3 back ticks…
```
```
If you now add your code between these, you will end up with it nicely formatted, which is then also easier for you to organise with the correct spacing and indentation etc. It’s also easier to spot any copy and paste issues such as the dash/minus sign one I’ve mentioned above.

For your Reversing an Array you should then end up with something like the following (I’ve also added a couple of additional points for you to consider concerning best practice):

var reverse = function(arr) {
   var result = [],   // Change the comma to a semi-colon; 
   ii = arr.length;   // Better practice to declare variable with a keyword
   for (var i = ii - 1; i !== 0; i--) {    // Condition needs correcting
      result.push(arr[i]);
   }
   return result;
}

console.log(reverse(['A', 'B', 'C', ]));

Have you had a go at the second part yet (reverseArrayInPlace)? Or did you reach saturation point? :wink:
If you didn’t really understand what was expected, have a look at the hints (which you can display in the online course book by clicking below the exercise instructions. If you still don’t get it, have a look at other students’ solutions posted here. Then if you’re still stuck let us know and we’ll help you out!

Remember, these exercises are very challenging and require you to take your time and really wrestle with the concepts.

Keep up the great work! :muscle:

Hey @ClapTrap!

Sorry for the delay in reviewing your answers to the Chapter 4 exercises.

I’ve just reviewed your code for The Sum of a Range so I wanted to get back to you without any further delay with my comments, then I’ll send you another post when I’ve reviewed the second exercise.

You’ve done a great job on the first exercise! :muscle:

You’ve dealt effectively with the issue of reverse stepping :+1:
The only situation it fails to handle correctly is if step is undefined AND we have a reverse range e.g.

console.log(sum(range(5, 2)));

It would be great to see if you can adapt your code to handle that too! I hope you’re up for the challenge!

Just a couple of further comments:
I don’t really understand this line of code in your solution.

numbers.length = 0;

It works, and at first I thought it was redundant, but if it’s removed, it doesn’t execute successfully. I’d be interested to know what your logic is behind it.

Personally, I think it’s clearer to remove this line, and then move the declaration of the array variable into the scope of the function like this:

function range(start, end, step) {
   let numbers = [];      /* Get into the habit of always declaring your
                             varaiables with keywords let, const or var */  
   // .... etc.
}

A more concise and clearer way to handle undefined arguments, is directly in the function header, like this:

function range (start, end, step = 1) { ... }

This achieves the same thing as your if statement, and so avoids having to add it.

if (step == undefined) {
   step = 1;
}

I hope that helps! :smiley:

1 Like

Hi again, @ClapTrap!

Reversing an array (returning a new array) :+1: Nice!
Yours is a good solution. Now thinking about how we can improve things even further…
Can you also see how using .unshift() in the for loop body…

reversedArray.unshift(array[i]);

… is more concise (and clearer?) than your…

reversedArray[i] = array[array.length-1-i];

Reversing an array (in place) :+1: Great!

You’re progressing really well! :muscle: Keep on learning! :smiley:

1 Like
let numbers=[];
    function range(start,end,step){
      numbers.length = 0;
      if (step==undefined){if (start<=end) step =1; else step=-1;};
      if (step<0){
        for(i=start;i>=end;i=i+step){
         numbers.push(i);
       }

     }else{
        for(i=start;i<=end;i=i+step){
         numbers.push(i);
       }
     }return numbers;
    }

Thanks for getting in touch, I just updated a correct version of the code which can handle BOTH undefined steps and reverse range.

numbers.length=0; is used to reset the Array so that it does not add a new array to an old one. You can easily see what happens removing and adding this command if you add these 2 lines to the bottom of the code:

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

Without numbers.length=0; the second array returns [1,3,5,7,9,5,4,3,2] instead of [5,4,3,2].
Defining numbers=[]; inside the function returns me an error of “Uncaught ReferenceError”, so I just added it outside.

With regard to the second exercise, I was somewhat insecure about the actual behavior of that function so I just coded it my self. I will be sure to check out that one as well as all the other jQuery functions.

Thanks again for the review.

1 Like

That’s great coding, @JustinP! :muscle:

Here are a few comments to help you build even more upon what already looks like excellent progress:

  • [""] no need for the quotes when you define an empty array i.e. it’s just [] . In fact what you’ve actually defined is an array with one element which is an empty string at newArray[0] . It doesn’t affect your code executing correctly, as you replace newArray[0] in your while loop anyway. However, it’s always good practice to tidy things up, in case it causes a bug if the code is developed futher.

  • Have a think about how you can merge these two lines into just one, to make it more concise:

    var lengthOfArray = (arrayToReverse.length)-1;  // parentheses not needed
    var counter = lengthOfArray;
  • Your solution is good, but did you try using a for loop as well? A for loop would be a more concise solution than using a while loop. Can you see why?

I’m not sure if you know, but before you enter your code to post it here in the forum, if you click on the </> icon in the menu at the top of the text editor. That will give you 2 sets of 3 back ticks…
```
```
If you now add your code between these, you will end up with it nicely formatted, which is then also easier for you to organise with the correct spacing and indentation etc. It’s also easier to spot any copy and paste issues that might have crept in.

For your Reversing an Array you should then end up with something like the following:

function reverseArray(arrayToReverse) {
   var newArray = [""];                           // quotes should be removed
   var lengthOfArray = arrayToReverse.length -1;  // combine this line...
   var counter = lengthOfArray;                   // ...with this line
   var newArrayCounter = 0;
   while (counter >= 0) {
      console.log("counter" + counter);
      newArray[newArrayCounter] = arrayToReverse[counter];
      counter--;
      newArrayCounter++;
   }
   return newArray
}

var myArray = ["Lions", "Tigers", "Bears", "Walrus", "Elephant"];

var animals = reverseArray(myArray);

console.log(animals);

Have you had a go at the second part yet ( reverseArrayInPlace )? Or did you reach saturation point? :wink:
If you didn’t really understand what was expected, have a look at the hints (which you can display in the online course book by clicking below the exercise instructions. If you still don’t get it, have a look at other students’ solutions posted here. Then if you’re still stuck let us know and we’ll help you out!

Remember, these exercises are very challenging and require you to take your time and really wrestle with the concepts.

Keep up the great work! :muscle:

1 Like

Hi @Ondrej.S!
Sorry for the delay in getting back to you with some feedback.

The Sum of a Range :+1: Great, your solution correctly sums a fixed array from 1-10 using “steps” of 1. However, the idea was to write 2 functions. You’ve posted the second one, sum , but what about the first one, range , which should be able to generate an array of any range of numbers based on start and end parameters? The sum function calls the range function within console.log  e.g.

console.log(sum(range(6, 9));
// an array [6, 7, 8, 9] will be passed to the sum function
// => 30

So, we want two functions that will be able to handle any combination of start and end arguments.

Have you tried the bonus assignment which introduces the step (interval) argument? If you haven’t, then I encourage you to do so. It’s a good challenge and will teach you a lot.

Post your additional code for what I’ve mentioned above and we’ll review it for you. If you didn’t really understand what was expected, have a look at the hints (which you can display in the online course book by clicking below the exercise instructions. If you still don’t get it, have a look at other students’ solutions posted here. Then if you’re still stuck let us know and we’ll help you out!

Remember, these exercises are very challenging and require you to take your time and really wrestle with the concepts.

I’m going to have a look at your second exercise now, but I just wanted to get back to you on the first exercise first.

1 Like

Hi again, @Ondrej.S!

Reversing an array (returning a new array) :+1: Nice!
Your use of the decrement operator in the for loop body is an interesting one. I haven’t come across that solution before! Very creative and innovative! :ok_hand: :smiley:

However, can you see how in the code you posted, the two minus signs (--) have changed to a dash ( – ) ? I’m assuming your original code did contain the correct decrement operator. If so, this is an excellent example of why it’s important to format your code when posting it.

Yours is a good solution. Now thinking about how we can improve things even further…
Can you also see how using .unshift() in the for loop body…

newArray.unshift(myArray[i]);

… is more concise (and clearer?) than your…

newArray[--newArrayIndex] = myArray[i];

Please feel free to disagree! There is nearly always more than one way to get an optimal result.

Have you had a go at the second part yet ( reverseArrayInPlace )? Or did you reach saturation point? :wink:

Keep up the great work! :muscle:

1 Like

Thanks for all of your help. I tried reverseArrayInPlace and got a partial solution (I’ve changed a few things based on your input). I got stuck because I couldn’t figure out how to get the new array returned properly. Then I looked at other solutions and realised it wasn’t really what was intended! I’ll have another go using the other strategy I saw…

Here’s my failed attempt:

  function reverseArrayInPlace(arrayToReverse){
    var newArray = [];
    var counter = (arrayToReverse.length)-1;
    var newArrayCounter = 0;
    while (counter >= 0){
      newArray[newArrayCounter] = arrayToReverse[counter];
      counter --;
      newArrayCounter++;
    }
    console.log("Array to reverse"+arrayToReverse);
    console.log("new array"+ newArray);
    arrayToReverse = newArray;
    return arrayToReverse;
  }

  var myArray = ["Lions", "Tigers", "Bears", "Walrus", "Elephant"];

  reverseArrayInPlace(myArray);

  console.log(myArray);



  </script>
type or paste code here

Got it! I think… I don’t fully understand though, why does this permanently change the contents of myArray? The function is working on it’s own ‘version’ of myArray called arrayToReverse, and that’s what it returned so why has myArray become arrayToReverse permanently?

  <script>
  function reverseArrayInPlace(arrayToReverse){
    var lengthOfArray = arrayToReverse.length;
    var halfLengthOfArray = Math.floor(arrayToReverse.length/2);
      for (var counter = 0; counter <= halfLengthOfArray; counter++){
        var holdingPlace = arrayToReverse[counter];
        arrayToReverse[counter]=arrayToReverse[lengthOfArray-1];
        arrayToReverse[lengthOfArray-1]=holdingPlace;
        lengthOfArray--;
      }
    return arrayToReverse;
    }


  var myArray = ["Lions", "Tigers", "Bears", "Walrus", "Elephant"];

  console.log(reverseArrayInPlace(myArray));
  console.log("MyArrayis now: " + myArray);




  </script>
1 Like

Thank you so much for this thorough feedback. I’m currently working on a trading bot in a different course but I was still planning to come back to this before starting C++. This will help me a lot. I’ll post another possible solution here later.

1 Like

Hi, I’m stuck on the reversing an array exercise I’ve looked at the solution and kinda understand it, but I still don’t know how I should solve the exercise, because I know that if I would try to do this exercise without looking at the solution I wouldn’t be able to do it. If I could get some help on “the reversing array”, I would be very grateful.

Sum of a range:

function range(start, end, step = 1){
        let numbers = [];
        if(start > end){
          if(step < 0){
          for(let i = start; i >= end; i += step){
            numbers.push(i);
            }
          }else{
            for(let i = start; i >= end; i -= step){
              numbers.push(i);
              }
          }
        }else{
          for(let i = start; i <= end; i += step){
            numbers.push(i);
         }
        }console.log(numbers)
        return numbers;
      };

      function sum(numbs){
        let result = 0;
        for(let i = 0; i < numbs.length; i++){
          result += numbs[0 + i];
        }return result;
      };

      console.log(sum([2,4,7]))
      console.log(sum(range(5,2,-1)));

Reverse Array:

let fruits = ["apple", "kiwi", "orange", "banana", "melon"];

      function reverseArray(array){
        let reverse = [];
        for(let i = array.length-1; i >= 0; i--){
          reverse.push(array[i]);
        }return reverse;
      };
      console.log(reverseArray(fruits));

Reverse Array In Place:
I needed a lot of help with this one :confused:

let fruits = ["apple", "kiwi", "orange", "banana", "melon"];
      function reverseArrayInPlace(array){
        for(let i = 0; i <= Math.floor((array.length-1)/2); i++){
          let item = array[i];
          array[i] = array[array.length-1-i];
          array[array.length-1-i] = item;
        }return array;
      };
      console.log(reverseArrayInPlace(fruits));

In the exercise description there was another thing:
“Thinking back to the notes about side effects and pure functions in the previous chapter, which variant do you expect to be useful in more situations? Which one runs faster?”
How can I figure out which one is faster? I feel like the reversing an array by creating a new array will run faster, but I can’t back this up with hard proofs.

1 Like
      // The sum of a range
      function createRangeArray(start, end) {
        var retval = [];
        for(var i = start; i <= end; ++i){
          retval.push(i);
        }
        return retval;
      }
      console.log(createRangeArray(15, 20));

      function sumArrayValues(inputArray) {
        var retval=0;
          for(var i in inputArray) {
            retval += inputArray[i];
          }
        return retval;
      }
      console.log(sumArrayValues(createRangeArray(1, 10)));

      function createRangeArrayStep(start, end, step = 1) {
        var retval = [];
        var reverseOrder = (start > end);
        for(var i = start; ; i += step) {
          // I don't like this if / else if code block
          // Using reverse arrays may result in a more "elegant" solution
          if(reverseOrder) {
            if(i < end)
              break;
          } else if (i > end){
            break;
          }
          retval.push(i);
        }
        return retval;
      }
      console.log(createRangeArrayStep(1, 10, 2));
      console.log(createRangeArrayStep(5, 2, -1));
      console.log(sumArrayValues(createRangeArrayStep(1, 10, 2)));
      console.log(sumArrayValues(createRangeArrayStep(5, 2, -1)));

      // Reversing an array
      function reverseArray(inputArray) {
        var retval = [];
        for (var i = inputArray.length - 1; i >= 0; --i){
          retval.push(inputArray[i]);
        }
        return retval;
      }
      console.log(reverseArray([1, 2, 3, 4, 5]));

      function reverseArrayInPlace(inputArray) {
        for (var i = 0; i <= inputArray.length/2; ++i){
          var tmp = inputArray[i]
          inputArray[i] = inputArray[inputArray.length - 1 - i];
          inputArray[inputArray.length - 1 - i] = tmp;
        }
        return inputArray;
      }
      console.log(reverseArray([1, 2, 3, 4, 5]));

      // The reverseArrayInPlace function will be faster than the reverseArray
      // because in the second one we iterate over all the input array. While in
      // the first one we just need to run the loop inputArray.length/2 times.
      // But I think that we could implement the reverseArray function in a simmilar way:

      // Reversing an array faster
      function reverseArrayV2(inputArray) {
        var arrayLength = inputArray.length;
        var retval = Array(arrayLength);
        for (var i = 0; i <= arrayLength/2; ++i){
          retval[i] = inputArray[arrayLength - 1 - i];
          retval[arrayLength - 1 - i] = inputArray[i];
        }
        return retval;
      }
      console.log(reverseArray([1, 2, 3, 4, 5]));

1 Like

Hi @Markus_Bielaszka!

Have you already tried looking at the hints (which you can display in the online course book by clicking below the exercise instructions. If you still don’t get it, let us know and we’ll give you some easier hints.

I’ll just add that the first part of the exercise needs to return a new array i.e. the input array should remain unmodified. Then in the second part you are reversing an array in place, which means the elements of the input array itself should be reversed within the function body, and so the same array is returned but modified.

1 Like

Thanks for the explanation, I understand what’s happening now. What confused me was the use of:

numbers.length = 0;

…as I would have instinctively gone for:

numbers = [];

Thanks for showing me an alternative :slightly_smiling_face: both seem to do exactly the same thing (they both work anyway).

Placing let numbers = []  inside the function (without  numbers.length = 0 ) doesn’t throw an error if you call sum like this:

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

Instead of passing numbers as the argument.

Anyway, great job!

1 Like

I wouldn’t be as harsh as to say “failed”, because your code works. It’s just that you aren’t really doing anything different to the first part, and the changes are just “cosmetic”, in that they don’t really provide any different functionality — you are still inputting one array (arrayToReverse), not modifying it, but instead creating a new array (newArray) which is a mirror image. You then make it seem like the input array was modified by reassigning the new array to its name:

1 Like