Need help with this Loop

Hey all, my name is State and I am new in this forum and also a beginner in programming. I read Kirupa Chinnathambi’s book on JavaScript, but could not find an example of how to code the code below. I will highly appreciate it if I can get help to understand how to go about it. Thanks in advance for your help.

let numbers = [
469,
755,
244,
245,
758,
450,
302,
20,
712,
71,
456,
21,
398,
339,
882,
848,
179,
535,
940,
472,
];
document.write("<h1>Array Analyzer</h1>")
document.write("<h3>Now analyzing the array: " + numbers + "</h3>");
document.write("<ul>");

:point_down:
let largestNumber;

Then how to render each li:
document.write(“

  • Largest Number: " + largestNumber + “
  • ”);
    etc…
    document.write(”");

    There are two parts to this. The first part is finding the largest number in the array and storing it in the largestNumber variable. The second part is printing it out on screen using document.write.

    The tricky part is the first step of finding the largest number in the array. Here is one approach you can use:

    1. Create a loop that is designed to through the numbers array

    2. Store the first item from the array to the largestNumber variable. This will be the first run of your loop.

    3. In the next run of your loop, check if the second number in the loop is larger than what you have already stored for largestNumber. If the number is larger, replace largestNumber with this number. If the number is smaller, just ignore the new number and let the loop continue.

    4. After your loop has fully run, the logic in step 3 will ensure that largestNumber stores a reference to the largest number in the array. You can then print the value of largest number out.

    This article and video can help you better get a feel for looping through an array:

    Hopefully this helps. Do reply back if you are stuck on any part of this :slight_smile:

    Cheers,
    Kirupa

    Thanks a million for your help. Still haven’t gotten the hang of it yet. Not your fault, still trying to understand the whole programming concept. I don.t even know how to start writing the code. With the help of people like you, I know I will understand the concept on the long run.
    Thanks again.

    You’ve come to the perfect place then :slight_smile:

    The video and article here can be a good starting point: https://www.kirupa.com/html5/building_your_first_web_page.htm

    If you have any questions here, please don’t hesitate to reply here or create a new topic. I and others here would be happy to work with you on any roadblocks you run into.

    Cheers,
    Kirupa

    Thanks very much Kirupa.

    let largestNumber = 0;

    for (let index = 0; index < numbers.length; index +=1){

    let currentNumber = numbers[index];

    if (currentNumber > largestNumber){

    largestNumber = currentNumber;

    }

    }
    document.write("

  • Largest Number: " + largestNumber + “
  • ”);

    I used the above code to get the largest number in the list, but I could not using the same method to get the desired results for the once below. Any suggestion please?
    Thanks.

    1. The smallest number in the array
    2. The sum of all the numbers in the array
    3. The average value of all the numbers in the array (the sum of all values divided by the number of values)
    4. A list of all even numbers in the array
    5. A list of all odd numbers in the array
    6. A list of all numbers divisible by 8 in the array

    Here’s a way of doing it.

    let numbers = [4,6,8,15,24,2,9,3,7,19];
        let evens = [];
        let eights = [];
        let odds = [];
        var sum = 0;
        var smallestNum = 0;
    var average = 0;
    
      
            smallestNum = numbers[0];
            for (i = 0; i < numbers.length; i++){
               sum += numbers[i];
                if (smallestNum > numbers[i]) smallestNum = numbers[i];
                if (numbers[i] % 8 == 0) eights.push(numbers[i]);
                if (numbers[i] % 2 == 0) evens.push(numbers[i]);
                if(numbers[i] % 2 !== 0) odds.push(numbers[i])
            }
    

    average = sum / numbers.length;

    Or you can create a reusable function that you pass in any array.

    let numbers = [4,6,8,15,24,2,9,3,7,19];
    
        const setValues = function (array){
            let evens = [];
            let eights = [];
            let odds = [];
            var sum = 0;
            var average = 0;
            smallestNum = 0;
    
    if (array[0] == null) return;
    smallestNum = array[0];
    
            for (i = 0; i < array.length; i++){
               sum += array[i];
                if (smallestNum > array[i]) smallestNum = array[i];
                if (array[i] % 8 == 0) eights.push(array[i]);
                if (array[i] % 2 == 0) evens.push(array[i]);
                if(array[i] % 2 !== 0) odds.push(array[i])
                }
                average = sum / array.length;
                let returnObj = {
                    evens: evens,
                    odds: odds,
                    eights: eights,
                    sum: sum,
                    average: average,
                    smallestNum: smallestNum,
                }
                return returnObj;
        };
        let results = setValues(numbers);
    
        console.log(results.evens);
        console.log(results.odds);
        console.log(results.sum);
        console.log(results);

    Hey Steve, thanks ever so much for your help. I am so grateful for this platform.

    no worries mate,
    It’s a bit verbose so you can understand whats happening.
    If your going to use it you probably should put in an empty array check and set smallestNum to a default

    var smallestNum = 0;
    

    then short circuit the function by checking for null or undefined with ==
    if(array[0] == null) return;
    smallestNum = array[0];

    1 Like

    That is the code I came up with, but it’s still giving me an error message. I must be doing something wrong. (code.js:72 Uncaught ReferenceError: EvenNumbers is not defined). Anytime I am able to sort out an error, another one comes on.

    let numbers = [469,755,244,245,758,450,302,20,712,71,456,21,398,339,882, 848179,535,940,472,
    ];
    const setValues = function (number){

    let evenNumbers = [];

    let eights = [];

    let odds = [];

    let sum = 0;

    let average = 0;

    smallestNumber = number[0];

    for (i = 0; i < number.length; i++){

    sum += number[i];

    if (smallestNumber > number[i]) smallestNum = number[index];

    if (numbers[index] % 2 == 0) evens.push(numbers[index]);

    if (numbers[index] % 2 !== 0) odds.push(numbers[index]);

    if (numbers[index] % 8 == 0) eights.push(numbers[index]);

    }

    average = sum / numbers.length;

    let returnObj = {

    evens: evens,

    odds: odds,

    eights: eights,

    sum: sum,

    average: average,

    smallestNumber: smallestNumber,

    }

    return returnObject;

    }

    document.write("

  • EvenNumbers: " + EvenNumbers + “
  • ”);

    document.write("

  • OddNumbers: " + oddNumbers + “
  • ”);

    document.write("

  • Results.sum: " + Results.sum + “
  • ”);

    document.write("

  • Results: " + Results + “
  • ”);

    document.write("

  • Smallest Number: " + smallestNumber + “
  • ”);

    Your naming conventions are too similar and you are mixing different things.

    When you call a function like this setValues(numbers);… and the function looks like this: const setValues = function(arr){ doSomething}… inside the function arr equals/ is referencing the array you called the function with (numbers).

    So if you want to use the function over and over you name the argument something like arr or array so it’s easy to understand / read and you don’t mix e.g. numbers with number.

    Also this i in the for loop is iteration or index ( i = 0;) which increments and the [ ] are property accessors.

    Every loop i increments 0,1,2 … so array[i] is saying get/ set array index of the value of i.

    You can also just say array[8] and get index 8 but that wouldn’t increment…

    You also need to call the function and save the results to a variable like let results = setValues(numbers).

    Then results will look like this after setValues runs:

    results = {
    average: 45065.68421052631,
    eights: [712, 456, 472],
    evens: [244, 758, 450, 302, 20, 712, 456, 398, 882, 940, 472],
    odds: [469, 755, 245, 71, 21, 339, 848179, 535],
    smallestNumber: 20,
    sum: 856248
    }

    You can access the values using dot notation: results.sum or bracket notation: results['sum'].

    You can also do this:

    var value = 'sum';
    console.log(results[value]) // logs results.sum;
    value = 'average';
    console.log(results[value]) // logs results.average;
    

    Which is also the same as:

    let numbers = [2,5,9,4]
    let index = 2;
    numbers[index] = ‘changed’; // is the same as numbers[2]
    console.log(numbers) // [2, 5, ‘changed’, 4]

    This is a more compact version that works

    let numbers = [469,755,244,245,758,450,302,20,712,71,456,21,398,339,882, 848179,535,940,472,
    
    ];
    
    const setValues = function (arr){
        if(arr[0] == null) return;
    
        let obj = {
            evens: [],
            odds: [],
            eights: [],
            sum: 0,
            average: 0,
            smallestNumber: 0,
        }
        obj.smallestNumber = arr[0];
    
        for (i = 0; i < arr.length; i++){
            obj.sum += arr[i];
            if (obj.smallestNumber > arr[i]) obj.smallestNumber = arr[i];
            if (arr[i] % 2 == 0) obj.evens.push(arr[i]);
            if (arr[i] % 2 !== 0) obj.odds.push(arr[i]);
            if (arr[i] % 8 == 0) obj.eights.push(arr[i]);
        }
    
        obj.average = obj.sum / arr.length;
    
        return obj;
    
    }
    
    let results = setValues(numbers);
    
    document.write(`Sum: ${results.sum}`)
    document.write(`Average: ${results.average}`) 
     document.write(`Smallest number: ${results.smallestNumber}`) 
    document.write(`Even numbers: ${results.evens.join(", ")}`)
    document.write(`Odd numbers: ${results.odds.join(", ")}`)
    document.write(`Numbers divisible by eight: ${results.eights.join(", ")}`)
    

    I hope this makes sense, if it doesn’t maybe go back through some videos and articles and go back over arrays, functions and arguments, property accessors, modulo operator and += operator. :slightly_smiling_face:

    On a side note: does anybody know why document.write() doesn’t respect template literal spacing or "\n" ?

    I can’t say that I have used document.write much or intend to use it much either. :slightly_smiling_face:

    FYI the standard for loop is so much more flexible than for of, for in or forEach.

    You have complete control over the iteration and can run multiple arrays through the loop.

    You can also make a map, reduce, filter ect function with a standard for loop.

    here’s an example of controlling iteration start/ end/ increment:

    let numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

    // function takes a start index, increment by 1+, finish index and array
    const loop = function(start, increment, end, array){

    // copies end value
    let fin = end;

    //copies increment value
    let iter = increment

    // checks if the end is more than the array length and resets if required
    if (end > array.length) fin = array.length;

    // avoids endless loops by not allowing 0 increment
    if (iter == 0 ) iter = 1;

    // array to return results
    let results = ;

    // sets i to start, finish at end, increments by incr e.g. every 3
    for(i = start; i < fin; i+= iter){

    //pushes the index/ iteration to results
    results.push(array[i]);
    }
    // returns an array from the function
    return results
    }
    console.log(loop(5,2,15,numbers));
    console.log(loop(0,3,numbers.length, numbers));
    console.log(loop(4,5,30, numbers));
    console.log(loop(2,25,55,numbers));

    If you can wrap your head around that you’ll see how power you have with for loops…


    Hi Steve,
    Thanks a lot, that was extremely helpful. How can I make my code to appear like the image above, instead of just a straight line?

    1 Like

    for a basic one, put your function and array (without document.write) in a <script> tag inside the document <head> and put the following below the function:

    > 
    > let results1 = setValues(numbers)
    > 
    > const writeHTML = function (arr, obj){
    >   let body = document.querySelector('body');
    >   body.innerHTML = `<h1>Array Analyser</h1>
    > <h3> Now Analyzing the array: ${arr.join(", ")}</h3>
    > <ul>
    >     ${(obj =>{if (obj.largestNumber) return `<li>Largest number: ${obj.largestNumber} </li>`; else return `` })(obj)}
    >     ${(obj =>{if (obj.smallestNumber) return `<li>Smallest number: ${obj.smallestNumber}</li>`; else return ``})(obj)}  
    >     ${(obj =>{if (obj.sum) return `<li>Sum: ${obj.sum}</li>`; return `` })(obj)}
    >     ${(obj =>{if (obj.average) return `<li>Average: ${obj.average}</li>`; else return `` })(obj)} 
    >     ${(obj =>{if (obj.evens) return `<li>Even numbers: ${obj.evens.join(", ")}</li>`; else return `` })(obj)} 
    >     ${(obj =>{if (obj.odds) return `<li>Odd numbers: ${obj.odds.join(", ")}</li>`; else return `` })(obj)} 
    >     ${(obj =>{if (obj.eights) return `<li>Numbers divisible by eight: ${obj.eights.join(", ")}</li>`; else return `` })(obj)} 
    > </ul>
    > `};
    > 
    > const run = () =>{ writeHTML(numbers, results)}
    > document.addEventListener('DOMContentLoaded', run)

    That function will also check to see if have/ don’t have a value e.g. if there isn’t a results.evens don’t write a list item.
    You can also return a custom response for an empty array:

     ${(obj =>{if (obj.eights && obj.eights.length !== 0) return `<li>Numbers divisible by eight: ${obj.eights.join(", ")}</li>`; else return `Numbers divisible by eight: none found` })(obj)
    

    That will return a custom message "Numbers divisible by eight: none found"

    1 Like

    Thanks, and thanks again Steve.

    2 Likes

    No worries mate, good luck…