Get the biggest chronological drop, min and max from an array with O(n)












7















I have written a javascript function for analyzing the biggest drop in an array. But one little issue is still there. As the max value, I always get max value from my hole array and not from my drop.



Example:
Array: [100,90,80,120]



The biggest drop would be between 100 and 80. So max must be 100, and min 80. My function always returns the highest value from the whole array. in my case 120



function checkData(data) {
let max = 0
let min = 0
let drop = 0

for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop, drop)
min = max - drop
}
}
return [max, min, drop]
}


I want to get the chronological correct biggest delta from left to right
Demo Image










share|improve this question




















  • 1





    When you say drop, do you mean difference?

    – cmprogram
    Nov 26 '18 at 12:40











  • @cmprogram, I mean the biggest delta between max an min.

    – Pommesloch
    Nov 26 '18 at 12:41








  • 1





    is this array sorted? what do you mean by saying drop?

    – yossico
    Nov 26 '18 at 12:41











  • return [max, min, drop] What are max, min and drop?

    – Wais Kamal
    Nov 26 '18 at 12:42











  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?

    – yossico
    Nov 26 '18 at 12:42


















7















I have written a javascript function for analyzing the biggest drop in an array. But one little issue is still there. As the max value, I always get max value from my hole array and not from my drop.



Example:
Array: [100,90,80,120]



The biggest drop would be between 100 and 80. So max must be 100, and min 80. My function always returns the highest value from the whole array. in my case 120



function checkData(data) {
let max = 0
let min = 0
let drop = 0

for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop, drop)
min = max - drop
}
}
return [max, min, drop]
}


I want to get the chronological correct biggest delta from left to right
Demo Image










share|improve this question




















  • 1





    When you say drop, do you mean difference?

    – cmprogram
    Nov 26 '18 at 12:40











  • @cmprogram, I mean the biggest delta between max an min.

    – Pommesloch
    Nov 26 '18 at 12:41








  • 1





    is this array sorted? what do you mean by saying drop?

    – yossico
    Nov 26 '18 at 12:41











  • return [max, min, drop] What are max, min and drop?

    – Wais Kamal
    Nov 26 '18 at 12:42











  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?

    – yossico
    Nov 26 '18 at 12:42
















7












7








7


1






I have written a javascript function for analyzing the biggest drop in an array. But one little issue is still there. As the max value, I always get max value from my hole array and not from my drop.



Example:
Array: [100,90,80,120]



The biggest drop would be between 100 and 80. So max must be 100, and min 80. My function always returns the highest value from the whole array. in my case 120



function checkData(data) {
let max = 0
let min = 0
let drop = 0

for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop, drop)
min = max - drop
}
}
return [max, min, drop]
}


I want to get the chronological correct biggest delta from left to right
Demo Image










share|improve this question
















I have written a javascript function for analyzing the biggest drop in an array. But one little issue is still there. As the max value, I always get max value from my hole array and not from my drop.



Example:
Array: [100,90,80,120]



The biggest drop would be between 100 and 80. So max must be 100, and min 80. My function always returns the highest value from the whole array. in my case 120



function checkData(data) {
let max = 0
let min = 0
let drop = 0

for (let i = 0; i < data.length; i++) {
if (max < data[i]) {
max = data[i] //?
} else {
let tempDrop = max - data[i]
drop = Math.max(tempDrop, drop)
min = max - drop
}
}
return [max, min, drop]
}


I want to get the chronological correct biggest delta from left to right
Demo Image







javascript arrays algorithm calculation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 13:20







Pommesloch

















asked Nov 26 '18 at 12:36









PommeslochPommesloch

308112




308112








  • 1





    When you say drop, do you mean difference?

    – cmprogram
    Nov 26 '18 at 12:40











  • @cmprogram, I mean the biggest delta between max an min.

    – Pommesloch
    Nov 26 '18 at 12:41








  • 1





    is this array sorted? what do you mean by saying drop?

    – yossico
    Nov 26 '18 at 12:41











  • return [max, min, drop] What are max, min and drop?

    – Wais Kamal
    Nov 26 '18 at 12:42











  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?

    – yossico
    Nov 26 '18 at 12:42
















  • 1





    When you say drop, do you mean difference?

    – cmprogram
    Nov 26 '18 at 12:40











  • @cmprogram, I mean the biggest delta between max an min.

    – Pommesloch
    Nov 26 '18 at 12:41








  • 1





    is this array sorted? what do you mean by saying drop?

    – yossico
    Nov 26 '18 at 12:41











  • return [max, min, drop] What are max, min and drop?

    – Wais Kamal
    Nov 26 '18 at 12:42











  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?

    – yossico
    Nov 26 '18 at 12:42










1




1





When you say drop, do you mean difference?

– cmprogram
Nov 26 '18 at 12:40





When you say drop, do you mean difference?

– cmprogram
Nov 26 '18 at 12:40













@cmprogram, I mean the biggest delta between max an min.

– Pommesloch
Nov 26 '18 at 12:41







@cmprogram, I mean the biggest delta between max an min.

– Pommesloch
Nov 26 '18 at 12:41






1




1





is this array sorted? what do you mean by saying drop?

– yossico
Nov 26 '18 at 12:41





is this array sorted? what do you mean by saying drop?

– yossico
Nov 26 '18 at 12:41













return [max, min, drop] What are max, min and drop?

– Wais Kamal
Nov 26 '18 at 12:42





return [max, min, drop] What are max, min and drop?

– Wais Kamal
Nov 26 '18 at 12:42













what would be the drop output to [100,110,120,70,60,50,90,300,200]?

– yossico
Nov 26 '18 at 12:42







what would be the drop output to [100,110,120,70,60,50,90,300,200]?

– yossico
Nov 26 '18 at 12:42














6 Answers
6






active

oldest

votes


















6














Your loop should keep track of the current drop and compare it to the previous largest drop. You can do this by tracking indexes:






function checkData(data) {
let bestDropStart = 0
let bestDropEnd = 0
let bestDrop = 0
let currentDropStart = 0
let currentDropEnd = 0
let currentDrop = 0
for (let i = 1; i < data.length; i++) {
if (data[i] < data[i - 1]) {
// we are dropping
currentDropEnd = i
currentDrop = data[currentDropStart] - data[i]
} else {
// the current drop ended; check if it's better
if (currentDrop > bestDrop) {
bestDrop = currentDrop
bestDropStart = currentDropStart
bestDropEnd = currentDropEnd
}
// start a new drop
currentDropStart = currentDropEnd = i
currentDrop = 0
}
}
// check for a best drop at end of data
if (currentDrop > bestDrop) {
bestDrop = currentDrop
bestDropStart = currentDropStart
bestDropEnd = currentDropEnd
}
// return the best drop data
return [data[bestDropStart], data[bestDropEnd], bestDrop]
}

console.log(checkData([100, 90, 80, 120]))
console.log(checkData([100, 90, 80, 120, 30]))
console.log(checkData([70, 100, 90, 80]))
console.log(checkData([100, 90, 80, 120, 30, 50]))





You can also do it by just keeping the start and end values for the current and best drops, but my preference would be to explicitly track the indexes. It just seems clearer (easier to debug and maintain) to me that way.






share|improve this answer

































    2














    It sounds like you'd like the returned max and min to be the same ones used in calculating the largest drop rather than the overall max and min. In that case just add an additional variable to store those when drop is updated. Replace



    drop = Math.max(tempDrop, drop)


    with an if statement (pseudocode):



    if current_drop is greater than stored_drop:
    stored_drop = current_drop
    stored_max_min = current max and min


    then return the additional stored max and min.






    share|improve this answer































      2














      You need to iterate the array once (O(n)) and keep a running count of min and max values and:




      1. Reset it every time the value increases w.r.t. previous value

      2. But note them down if the difference is greater than previously noted values





      function checkData(array) {
      var currentmax = array[0];
      var currentmin = array[0];
      var overallmax = array[0];
      var overallmin = array[0];
      var i;
      for (i = 1; i < array.length; i++) {
      if (array[i] <= array[i - 1]) {
      // value is same or decreased
      currentmin = array[i];
      } else {
      // check if previous iteration was the largest
      if (currentmax - currentmin > overallmax - overallmin) {
      overallmax = currentmax;
      overallmin = currentmin;
      }
      // restart
      currentmax = array[i];
      currentmin = array[i];
      }
      }
      // check if last iteration was the largest
      if (currentmax - currentmin > overallmax - overallmin) {
      overallmax = currentmax;
      overallmin = currentmin;
      }

      return [overallmax, overallmin, overallmax - overallmin];
      }
      console.log(checkData([100, 90, 80, 120]));
      console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
      console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));








      share|improve this answer


























      • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

        – Pommesloch
        Nov 26 '18 at 13:50






      • 1





        the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

        – Salman A
        Nov 26 '18 at 13:55





















      0














      You need to keep track of two things:




      • The maximum value you have up to an element i.

      • The minimum value you have from an element i to the end of the list.


      Then you just need to find the drop for each index and select which one is biggest.



      Here is the code:






      function maxDrop (data) {
      if (!data || data.length === 0) {
      return;
      }
      const max = ;
      const min = ;
      for (let i = 0; i < data.length; i++) {
      const left = data.slice(0, i);
      const right = data.slice(i, data.length);
      max.push(Math.max.apply(null, left));
      min.push(Math.min.apply(null, right));
      }
      let maxDrop = max[0] - min[0];
      let maxValue = max[0];
      let minValue = min[0];
      for (let j = 0; j < data.length; j++) {
      const drop = max[j] - min[j];
      if (maxDrop < drop) {
      maxDrop = drop;
      maxValue = max[j];
      minValue = min[j];
      }
      }
      return [maxValue, minValue, maxDrop];
      }

      console.log(maxDrop([100,90,80,120]))
      console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
      console.log(maxDrop([100,90,80,120,30]))








      share|improve this answer


























      • This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

        – Ted Hopp
        Nov 26 '18 at 13:37











      • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

        – kakamg0
        Nov 26 '18 at 13:56



















      0














      To add one more to the mix..
      A possible approach is to create all the drop - ranges first, than get the one with the largest drop



      A version with reduce:






      function checkData(data) {
      let dropInd = 1,
      mx = data.reduce((arr,val, ind) => {
      if(ind && val > data[ind-1])dropInd++;
      arr[dropInd] = arr[dropInd] || {max:val};
      arr[dropInd].min = val;
      arr[dropInd].drop = arr[dropInd].max - val;
      return arr;
      }, ) //after reduce, islands are created based on 'dropInd'
      .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
      [0]; //the first value now contains the maximum drop

      return [mx.max,mx.min,mx.drop];
      }



      console.log(checkData([100, 90, 80, 120]));
      console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
      console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
      console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));








      share|improve this answer

































        -1














        This works exactly as intended (as per your expected output), as shown in the following code snippet.



        The issue must be in how you are sending your data as an array.






        alert(checkData([100, 90, 80, 120]));

        function checkData(data) {
        let max = 0
        let min = 0
        let drop = 0

        for (let i = 0; i < data.length; i++) {
        if (max < data[i]) {
        max = data[i] //?
        } else {
        let tempDrop = max - data[i]
        drop = Math.max(tempDrop)
        min = max - drop
        }
        }
        return [max, min, drop]
        }





        // Output : 120, 80, 20


        However, if what you are looking for is a Max, a Min, and then the biggest difference, i.e. between the the max and min, which in your given example would be 40, then you can simply do this.






        alert(checkData([100, 90, 80, 120]));

        function checkData(data) {

        let max = data.reduce(function(a, b) {
        return Math.max(a, b);
        });
        let min = data.reduce(function(a, b) {
        return Math.min(a, b);
        });

        let drop = max-min;

        return [max, min, drop];

        }





        // Output : 120, 80, 40


        I only mention this as I don't know why you've said you expect the biggest difference to be 20, given 100 and 80, when you have 120 and 80 in the same array, meaning the biggest difference is 40.






        share|improve this answer


























        • Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

          – Pommesloch
          Nov 26 '18 at 13:11











        • But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

          – cmprogram
          Nov 26 '18 at 13:13











        • This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

          – Pommesloch
          Nov 26 '18 at 13:18






        • 1





          OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

          – Ted Hopp
          Nov 26 '18 at 13:34












        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53481266%2fget-the-biggest-chronological-drop-min-and-max-from-an-array-with-on%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        6 Answers
        6






        active

        oldest

        votes








        6 Answers
        6






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        6














        Your loop should keep track of the current drop and compare it to the previous largest drop. You can do this by tracking indexes:






        function checkData(data) {
        let bestDropStart = 0
        let bestDropEnd = 0
        let bestDrop = 0
        let currentDropStart = 0
        let currentDropEnd = 0
        let currentDrop = 0
        for (let i = 1; i < data.length; i++) {
        if (data[i] < data[i - 1]) {
        // we are dropping
        currentDropEnd = i
        currentDrop = data[currentDropStart] - data[i]
        } else {
        // the current drop ended; check if it's better
        if (currentDrop > bestDrop) {
        bestDrop = currentDrop
        bestDropStart = currentDropStart
        bestDropEnd = currentDropEnd
        }
        // start a new drop
        currentDropStart = currentDropEnd = i
        currentDrop = 0
        }
        }
        // check for a best drop at end of data
        if (currentDrop > bestDrop) {
        bestDrop = currentDrop
        bestDropStart = currentDropStart
        bestDropEnd = currentDropEnd
        }
        // return the best drop data
        return [data[bestDropStart], data[bestDropEnd], bestDrop]
        }

        console.log(checkData([100, 90, 80, 120]))
        console.log(checkData([100, 90, 80, 120, 30]))
        console.log(checkData([70, 100, 90, 80]))
        console.log(checkData([100, 90, 80, 120, 30, 50]))





        You can also do it by just keeping the start and end values for the current and best drops, but my preference would be to explicitly track the indexes. It just seems clearer (easier to debug and maintain) to me that way.






        share|improve this answer






























          6














          Your loop should keep track of the current drop and compare it to the previous largest drop. You can do this by tracking indexes:






          function checkData(data) {
          let bestDropStart = 0
          let bestDropEnd = 0
          let bestDrop = 0
          let currentDropStart = 0
          let currentDropEnd = 0
          let currentDrop = 0
          for (let i = 1; i < data.length; i++) {
          if (data[i] < data[i - 1]) {
          // we are dropping
          currentDropEnd = i
          currentDrop = data[currentDropStart] - data[i]
          } else {
          // the current drop ended; check if it's better
          if (currentDrop > bestDrop) {
          bestDrop = currentDrop
          bestDropStart = currentDropStart
          bestDropEnd = currentDropEnd
          }
          // start a new drop
          currentDropStart = currentDropEnd = i
          currentDrop = 0
          }
          }
          // check for a best drop at end of data
          if (currentDrop > bestDrop) {
          bestDrop = currentDrop
          bestDropStart = currentDropStart
          bestDropEnd = currentDropEnd
          }
          // return the best drop data
          return [data[bestDropStart], data[bestDropEnd], bestDrop]
          }

          console.log(checkData([100, 90, 80, 120]))
          console.log(checkData([100, 90, 80, 120, 30]))
          console.log(checkData([70, 100, 90, 80]))
          console.log(checkData([100, 90, 80, 120, 30, 50]))





          You can also do it by just keeping the start and end values for the current and best drops, but my preference would be to explicitly track the indexes. It just seems clearer (easier to debug and maintain) to me that way.






          share|improve this answer




























            6












            6








            6







            Your loop should keep track of the current drop and compare it to the previous largest drop. You can do this by tracking indexes:






            function checkData(data) {
            let bestDropStart = 0
            let bestDropEnd = 0
            let bestDrop = 0
            let currentDropStart = 0
            let currentDropEnd = 0
            let currentDrop = 0
            for (let i = 1; i < data.length; i++) {
            if (data[i] < data[i - 1]) {
            // we are dropping
            currentDropEnd = i
            currentDrop = data[currentDropStart] - data[i]
            } else {
            // the current drop ended; check if it's better
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // start a new drop
            currentDropStart = currentDropEnd = i
            currentDrop = 0
            }
            }
            // check for a best drop at end of data
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // return the best drop data
            return [data[bestDropStart], data[bestDropEnd], bestDrop]
            }

            console.log(checkData([100, 90, 80, 120]))
            console.log(checkData([100, 90, 80, 120, 30]))
            console.log(checkData([70, 100, 90, 80]))
            console.log(checkData([100, 90, 80, 120, 30, 50]))





            You can also do it by just keeping the start and end values for the current and best drops, but my preference would be to explicitly track the indexes. It just seems clearer (easier to debug and maintain) to me that way.






            share|improve this answer















            Your loop should keep track of the current drop and compare it to the previous largest drop. You can do this by tracking indexes:






            function checkData(data) {
            let bestDropStart = 0
            let bestDropEnd = 0
            let bestDrop = 0
            let currentDropStart = 0
            let currentDropEnd = 0
            let currentDrop = 0
            for (let i = 1; i < data.length; i++) {
            if (data[i] < data[i - 1]) {
            // we are dropping
            currentDropEnd = i
            currentDrop = data[currentDropStart] - data[i]
            } else {
            // the current drop ended; check if it's better
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // start a new drop
            currentDropStart = currentDropEnd = i
            currentDrop = 0
            }
            }
            // check for a best drop at end of data
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // return the best drop data
            return [data[bestDropStart], data[bestDropEnd], bestDrop]
            }

            console.log(checkData([100, 90, 80, 120]))
            console.log(checkData([100, 90, 80, 120, 30]))
            console.log(checkData([70, 100, 90, 80]))
            console.log(checkData([100, 90, 80, 120, 30, 50]))





            You can also do it by just keeping the start and end values for the current and best drops, but my preference would be to explicitly track the indexes. It just seems clearer (easier to debug and maintain) to me that way.






            function checkData(data) {
            let bestDropStart = 0
            let bestDropEnd = 0
            let bestDrop = 0
            let currentDropStart = 0
            let currentDropEnd = 0
            let currentDrop = 0
            for (let i = 1; i < data.length; i++) {
            if (data[i] < data[i - 1]) {
            // we are dropping
            currentDropEnd = i
            currentDrop = data[currentDropStart] - data[i]
            } else {
            // the current drop ended; check if it's better
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // start a new drop
            currentDropStart = currentDropEnd = i
            currentDrop = 0
            }
            }
            // check for a best drop at end of data
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // return the best drop data
            return [data[bestDropStart], data[bestDropEnd], bestDrop]
            }

            console.log(checkData([100, 90, 80, 120]))
            console.log(checkData([100, 90, 80, 120, 30]))
            console.log(checkData([70, 100, 90, 80]))
            console.log(checkData([100, 90, 80, 120, 30, 50]))





            function checkData(data) {
            let bestDropStart = 0
            let bestDropEnd = 0
            let bestDrop = 0
            let currentDropStart = 0
            let currentDropEnd = 0
            let currentDrop = 0
            for (let i = 1; i < data.length; i++) {
            if (data[i] < data[i - 1]) {
            // we are dropping
            currentDropEnd = i
            currentDrop = data[currentDropStart] - data[i]
            } else {
            // the current drop ended; check if it's better
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // start a new drop
            currentDropStart = currentDropEnd = i
            currentDrop = 0
            }
            }
            // check for a best drop at end of data
            if (currentDrop > bestDrop) {
            bestDrop = currentDrop
            bestDropStart = currentDropStart
            bestDropEnd = currentDropEnd
            }
            // return the best drop data
            return [data[bestDropStart], data[bestDropEnd], bestDrop]
            }

            console.log(checkData([100, 90, 80, 120]))
            console.log(checkData([100, 90, 80, 120, 30]))
            console.log(checkData([70, 100, 90, 80]))
            console.log(checkData([100, 90, 80, 120, 30, 50]))






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 26 '18 at 15:39

























            answered Nov 26 '18 at 13:56









            Ted HoppTed Hopp

            201k42317431




            201k42317431

























                2














                It sounds like you'd like the returned max and min to be the same ones used in calculating the largest drop rather than the overall max and min. In that case just add an additional variable to store those when drop is updated. Replace



                drop = Math.max(tempDrop, drop)


                with an if statement (pseudocode):



                if current_drop is greater than stored_drop:
                stored_drop = current_drop
                stored_max_min = current max and min


                then return the additional stored max and min.






                share|improve this answer




























                  2














                  It sounds like you'd like the returned max and min to be the same ones used in calculating the largest drop rather than the overall max and min. In that case just add an additional variable to store those when drop is updated. Replace



                  drop = Math.max(tempDrop, drop)


                  with an if statement (pseudocode):



                  if current_drop is greater than stored_drop:
                  stored_drop = current_drop
                  stored_max_min = current max and min


                  then return the additional stored max and min.






                  share|improve this answer


























                    2












                    2








                    2







                    It sounds like you'd like the returned max and min to be the same ones used in calculating the largest drop rather than the overall max and min. In that case just add an additional variable to store those when drop is updated. Replace



                    drop = Math.max(tempDrop, drop)


                    with an if statement (pseudocode):



                    if current_drop is greater than stored_drop:
                    stored_drop = current_drop
                    stored_max_min = current max and min


                    then return the additional stored max and min.






                    share|improve this answer













                    It sounds like you'd like the returned max and min to be the same ones used in calculating the largest drop rather than the overall max and min. In that case just add an additional variable to store those when drop is updated. Replace



                    drop = Math.max(tempDrop, drop)


                    with an if statement (pseudocode):



                    if current_drop is greater than stored_drop:
                    stored_drop = current_drop
                    stored_max_min = current max and min


                    then return the additional stored max and min.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 26 '18 at 13:39









                    גלעד ברקןגלעד ברקן

                    13.6k21544




                    13.6k21544























                        2














                        You need to iterate the array once (O(n)) and keep a running count of min and max values and:




                        1. Reset it every time the value increases w.r.t. previous value

                        2. But note them down if the difference is greater than previously noted values





                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));








                        share|improve this answer


























                        • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                          – Pommesloch
                          Nov 26 '18 at 13:50






                        • 1





                          the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                          – Salman A
                          Nov 26 '18 at 13:55


















                        2














                        You need to iterate the array once (O(n)) and keep a running count of min and max values and:




                        1. Reset it every time the value increases w.r.t. previous value

                        2. But note them down if the difference is greater than previously noted values





                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));








                        share|improve this answer


























                        • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                          – Pommesloch
                          Nov 26 '18 at 13:50






                        • 1





                          the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                          – Salman A
                          Nov 26 '18 at 13:55
















                        2












                        2








                        2







                        You need to iterate the array once (O(n)) and keep a running count of min and max values and:




                        1. Reset it every time the value increases w.r.t. previous value

                        2. But note them down if the difference is greater than previously noted values





                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));








                        share|improve this answer















                        You need to iterate the array once (O(n)) and keep a running count of min and max values and:




                        1. Reset it every time the value increases w.r.t. previous value

                        2. But note them down if the difference is greater than previously noted values





                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));








                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));





                        function checkData(array) {
                        var currentmax = array[0];
                        var currentmin = array[0];
                        var overallmax = array[0];
                        var overallmin = array[0];
                        var i;
                        for (i = 1; i < array.length; i++) {
                        if (array[i] <= array[i - 1]) {
                        // value is same or decreased
                        currentmin = array[i];
                        } else {
                        // check if previous iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }
                        // restart
                        currentmax = array[i];
                        currentmin = array[i];
                        }
                        }
                        // check if last iteration was the largest
                        if (currentmax - currentmin > overallmax - overallmin) {
                        overallmax = currentmax;
                        overallmin = currentmin;
                        }

                        return [overallmax, overallmin, overallmax - overallmin];
                        }
                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100, 90]));
                        console.log(checkData([10, 100, 50, 50, 10, 100, 50, 50, 1]));






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Nov 26 '18 at 15:16

























                        answered Nov 26 '18 at 13:36









                        Salman ASalman A

                        185k67344441




                        185k67344441













                        • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                          – Pommesloch
                          Nov 26 '18 at 13:50






                        • 1





                          the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                          – Salman A
                          Nov 26 '18 at 13:55





















                        • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                          – Pommesloch
                          Nov 26 '18 at 13:50






                        • 1





                          the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                          – Salman A
                          Nov 26 '18 at 13:55



















                        This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                        – Pommesloch
                        Nov 26 '18 at 13:50





                        This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110

                        – Pommesloch
                        Nov 26 '18 at 13:50




                        1




                        1





                        the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                        – Salman A
                        Nov 26 '18 at 13:55







                        the logic is sound (I think) and i just need to update the max min everytime the values change. See revised answer.

                        – Salman A
                        Nov 26 '18 at 13:55













                        0














                        You need to keep track of two things:




                        • The maximum value you have up to an element i.

                        • The minimum value you have from an element i to the end of the list.


                        Then you just need to find the drop for each index and select which one is biggest.



                        Here is the code:






                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))








                        share|improve this answer


























                        • This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                          – Ted Hopp
                          Nov 26 '18 at 13:37











                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                          – kakamg0
                          Nov 26 '18 at 13:56
















                        0














                        You need to keep track of two things:




                        • The maximum value you have up to an element i.

                        • The minimum value you have from an element i to the end of the list.


                        Then you just need to find the drop for each index and select which one is biggest.



                        Here is the code:






                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))








                        share|improve this answer


























                        • This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                          – Ted Hopp
                          Nov 26 '18 at 13:37











                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                          – kakamg0
                          Nov 26 '18 at 13:56














                        0












                        0








                        0







                        You need to keep track of two things:




                        • The maximum value you have up to an element i.

                        • The minimum value you have from an element i to the end of the list.


                        Then you just need to find the drop for each index and select which one is biggest.



                        Here is the code:






                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))








                        share|improve this answer















                        You need to keep track of two things:




                        • The maximum value you have up to an element i.

                        • The minimum value you have from an element i to the end of the list.


                        Then you just need to find the drop for each index and select which one is biggest.



                        Here is the code:






                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))








                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))





                        function maxDrop (data) {
                        if (!data || data.length === 0) {
                        return;
                        }
                        const max = ;
                        const min = ;
                        for (let i = 0; i < data.length; i++) {
                        const left = data.slice(0, i);
                        const right = data.slice(i, data.length);
                        max.push(Math.max.apply(null, left));
                        min.push(Math.min.apply(null, right));
                        }
                        let maxDrop = max[0] - min[0];
                        let maxValue = max[0];
                        let minValue = min[0];
                        for (let j = 0; j < data.length; j++) {
                        const drop = max[j] - min[j];
                        if (maxDrop < drop) {
                        maxDrop = drop;
                        maxValue = max[j];
                        minValue = min[j];
                        }
                        }
                        return [maxValue, minValue, maxDrop];
                        }

                        console.log(maxDrop([100,90,80,120]))
                        console.log(maxDrop([100,110,120,300,200,70,60,50,90,400]))
                        console.log(maxDrop([100,90,80,120,30]))






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Nov 26 '18 at 13:55

























                        answered Nov 26 '18 at 13:34









                        kakamg0kakamg0

                        901412




                        901412













                        • This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                          – Ted Hopp
                          Nov 26 '18 at 13:37











                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                          – kakamg0
                          Nov 26 '18 at 13:56



















                        • This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                          – Ted Hopp
                          Nov 26 '18 at 13:37











                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                          – kakamg0
                          Nov 26 '18 at 13:56

















                        This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                        – Ted Hopp
                        Nov 26 '18 at 13:37





                        This fails for [100, 90, 80, 120, 30]. The output is [100, 80, 20] but it should be [120, 30, 90].

                        – Ted Hopp
                        Nov 26 '18 at 13:37













                        @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                        – kakamg0
                        Nov 26 '18 at 13:56





                        @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!

                        – kakamg0
                        Nov 26 '18 at 13:56











                        0














                        To add one more to the mix..
                        A possible approach is to create all the drop - ranges first, than get the one with the largest drop



                        A version with reduce:






                        function checkData(data) {
                        let dropInd = 1,
                        mx = data.reduce((arr,val, ind) => {
                        if(ind && val > data[ind-1])dropInd++;
                        arr[dropInd] = arr[dropInd] || {max:val};
                        arr[dropInd].min = val;
                        arr[dropInd].drop = arr[dropInd].max - val;
                        return arr;
                        }, ) //after reduce, islands are created based on 'dropInd'
                        .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                        [0]; //the first value now contains the maximum drop

                        return [mx.max,mx.min,mx.drop];
                        }



                        console.log(checkData([100, 90, 80, 120]));
                        console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                        console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                        console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));








                        share|improve this answer






























                          0














                          To add one more to the mix..
                          A possible approach is to create all the drop - ranges first, than get the one with the largest drop



                          A version with reduce:






                          function checkData(data) {
                          let dropInd = 1,
                          mx = data.reduce((arr,val, ind) => {
                          if(ind && val > data[ind-1])dropInd++;
                          arr[dropInd] = arr[dropInd] || {max:val};
                          arr[dropInd].min = val;
                          arr[dropInd].drop = arr[dropInd].max - val;
                          return arr;
                          }, ) //after reduce, islands are created based on 'dropInd'
                          .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                          [0]; //the first value now contains the maximum drop

                          return [mx.max,mx.min,mx.drop];
                          }



                          console.log(checkData([100, 90, 80, 120]));
                          console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                          console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                          console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));








                          share|improve this answer




























                            0












                            0








                            0







                            To add one more to the mix..
                            A possible approach is to create all the drop - ranges first, than get the one with the largest drop



                            A version with reduce:






                            function checkData(data) {
                            let dropInd = 1,
                            mx = data.reduce((arr,val, ind) => {
                            if(ind && val > data[ind-1])dropInd++;
                            arr[dropInd] = arr[dropInd] || {max:val};
                            arr[dropInd].min = val;
                            arr[dropInd].drop = arr[dropInd].max - val;
                            return arr;
                            }, ) //after reduce, islands are created based on 'dropInd'
                            .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                            [0]; //the first value now contains the maximum drop

                            return [mx.max,mx.min,mx.drop];
                            }



                            console.log(checkData([100, 90, 80, 120]));
                            console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                            console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                            console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));








                            share|improve this answer















                            To add one more to the mix..
                            A possible approach is to create all the drop - ranges first, than get the one with the largest drop



                            A version with reduce:






                            function checkData(data) {
                            let dropInd = 1,
                            mx = data.reduce((arr,val, ind) => {
                            if(ind && val > data[ind-1])dropInd++;
                            arr[dropInd] = arr[dropInd] || {max:val};
                            arr[dropInd].min = val;
                            arr[dropInd].drop = arr[dropInd].max - val;
                            return arr;
                            }, ) //after reduce, islands are created based on 'dropInd'
                            .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                            [0]; //the first value now contains the maximum drop

                            return [mx.max,mx.min,mx.drop];
                            }



                            console.log(checkData([100, 90, 80, 120]));
                            console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                            console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                            console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));








                            function checkData(data) {
                            let dropInd = 1,
                            mx = data.reduce((arr,val, ind) => {
                            if(ind && val > data[ind-1])dropInd++;
                            arr[dropInd] = arr[dropInd] || {max:val};
                            arr[dropInd].min = val;
                            arr[dropInd].drop = arr[dropInd].max - val;
                            return arr;
                            }, ) //after reduce, islands are created based on 'dropInd'
                            .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                            [0]; //the first value now contains the maximum drop

                            return [mx.max,mx.min,mx.drop];
                            }



                            console.log(checkData([100, 90, 80, 120]));
                            console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                            console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                            console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));





                            function checkData(data) {
                            let dropInd = 1,
                            mx = data.reduce((arr,val, ind) => {
                            if(ind && val > data[ind-1])dropInd++;
                            arr[dropInd] = arr[dropInd] || {max:val};
                            arr[dropInd].min = val;
                            arr[dropInd].drop = arr[dropInd].max - val;
                            return arr;
                            }, ) //after reduce, islands are created based on 'dropInd'
                            .sort((v1,v2)=>v2.drop - v1.drop) //sort by drop descending
                            [0]; //the first value now contains the maximum drop

                            return [mx.max,mx.min,mx.drop];
                            }



                            console.log(checkData([100, 90, 80, 120]));
                            console.log(checkData([100, 90, 80, 120, 200, 100 ,90]));
                            console.log(checkData([200,100, 90, 80, 120, 100 ,90]));
                            console.log(checkData([200,120,190, 90, 80, 120, 100 ,90]));






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 26 '18 at 16:17

























                            answered Nov 26 '18 at 14:12









                            Me.NameMe.Name

                            10.2k22039




                            10.2k22039























                                -1














                                This works exactly as intended (as per your expected output), as shown in the following code snippet.



                                The issue must be in how you are sending your data as an array.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                // Output : 120, 80, 20


                                However, if what you are looking for is a Max, a Min, and then the biggest difference, i.e. between the the max and min, which in your given example would be 40, then you can simply do this.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }





                                // Output : 120, 80, 40


                                I only mention this as I don't know why you've said you expect the biggest difference to be 20, given 100 and 80, when you have 120 and 80 in the same array, meaning the biggest difference is 40.






                                share|improve this answer


























                                • Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                  – Pommesloch
                                  Nov 26 '18 at 13:11











                                • But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                  – cmprogram
                                  Nov 26 '18 at 13:13











                                • This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                  – Pommesloch
                                  Nov 26 '18 at 13:18






                                • 1





                                  OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                  – Ted Hopp
                                  Nov 26 '18 at 13:34
















                                -1














                                This works exactly as intended (as per your expected output), as shown in the following code snippet.



                                The issue must be in how you are sending your data as an array.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                // Output : 120, 80, 20


                                However, if what you are looking for is a Max, a Min, and then the biggest difference, i.e. between the the max and min, which in your given example would be 40, then you can simply do this.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }





                                // Output : 120, 80, 40


                                I only mention this as I don't know why you've said you expect the biggest difference to be 20, given 100 and 80, when you have 120 and 80 in the same array, meaning the biggest difference is 40.






                                share|improve this answer


























                                • Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                  – Pommesloch
                                  Nov 26 '18 at 13:11











                                • But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                  – cmprogram
                                  Nov 26 '18 at 13:13











                                • This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                  – Pommesloch
                                  Nov 26 '18 at 13:18






                                • 1





                                  OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                  – Ted Hopp
                                  Nov 26 '18 at 13:34














                                -1












                                -1








                                -1







                                This works exactly as intended (as per your expected output), as shown in the following code snippet.



                                The issue must be in how you are sending your data as an array.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                // Output : 120, 80, 20


                                However, if what you are looking for is a Max, a Min, and then the biggest difference, i.e. between the the max and min, which in your given example would be 40, then you can simply do this.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }





                                // Output : 120, 80, 40


                                I only mention this as I don't know why you've said you expect the biggest difference to be 20, given 100 and 80, when you have 120 and 80 in the same array, meaning the biggest difference is 40.






                                share|improve this answer















                                This works exactly as intended (as per your expected output), as shown in the following code snippet.



                                The issue must be in how you are sending your data as an array.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                // Output : 120, 80, 20


                                However, if what you are looking for is a Max, a Min, and then the biggest difference, i.e. between the the max and min, which in your given example would be 40, then you can simply do this.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }





                                // Output : 120, 80, 40


                                I only mention this as I don't know why you've said you expect the biggest difference to be 20, given 100 and 80, when you have 120 and 80 in the same array, meaning the biggest difference is 40.






                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {
                                let max = 0
                                let min = 0
                                let drop = 0

                                for (let i = 0; i < data.length; i++) {
                                if (max < data[i]) {
                                max = data[i] //?
                                } else {
                                let tempDrop = max - data[i]
                                drop = Math.max(tempDrop)
                                min = max - drop
                                }
                                }
                                return [max, min, drop]
                                }





                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }





                                alert(checkData([100, 90, 80, 120]));

                                function checkData(data) {

                                let max = data.reduce(function(a, b) {
                                return Math.max(a, b);
                                });
                                let min = data.reduce(function(a, b) {
                                return Math.min(a, b);
                                });

                                let drop = max-min;

                                return [max, min, drop];

                                }






                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Nov 26 '18 at 13:01

























                                answered Nov 26 '18 at 12:50









                                cmprogramcmprogram

                                1,3091720




                                1,3091720













                                • Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                  – Pommesloch
                                  Nov 26 '18 at 13:11











                                • But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                  – cmprogram
                                  Nov 26 '18 at 13:13











                                • This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                  – Pommesloch
                                  Nov 26 '18 at 13:18






                                • 1





                                  OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                  – Ted Hopp
                                  Nov 26 '18 at 13:34



















                                • Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                  – Pommesloch
                                  Nov 26 '18 at 13:11











                                • But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                  – cmprogram
                                  Nov 26 '18 at 13:13











                                • This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                  – Pommesloch
                                  Nov 26 '18 at 13:18






                                • 1





                                  OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                  – Ted Hopp
                                  Nov 26 '18 at 13:34

















                                Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                – Pommesloch
                                Nov 26 '18 at 13:11





                                Thanks, but the correct return must be max = 100, min = 80 and drop = 20. Look at the graphic that I added to my post

                                – Pommesloch
                                Nov 26 '18 at 13:11













                                But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                – cmprogram
                                Nov 26 '18 at 13:13





                                But 100 isn't the max... If you don't want the 120 to be included, just don't include it in the array...

                                – cmprogram
                                Nov 26 '18 at 13:13













                                This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                – Pommesloch
                                Nov 26 '18 at 13:18





                                This data comes from a shares API. That is why I need this chronological from left to right delta. The shares course is crashed here from 100 to 80. This is a -20% drop. In my attempt, I miss the chronological aspect

                                – Pommesloch
                                Nov 26 '18 at 13:18




                                1




                                1





                                OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                – Ted Hopp
                                Nov 26 '18 at 13:34





                                OP wants the max and min associated with the largest drop, where a drop is a sequence of descending data values. The largest drop is from 100 to 80 (indexes 0 through 2).

                                – Ted Hopp
                                Nov 26 '18 at 13:34


















                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53481266%2fget-the-biggest-chronological-drop-min-and-max-from-an-array-with-on%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Costa Masnaga

                                Fotorealismo

                                Sidney Franklin