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











up vote
8
down vote

favorite
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




















  • 1




    When you say drop, do you mean difference?
    – cmprogram
    Nov 26 at 12:40










  • @cmprogram, I mean the biggest delta between max an min.
    – Pommesloch
    Nov 26 at 12:41








  • 1




    is this array sorted? what do you mean by saying drop?
    – yossico
    Nov 26 at 12:41










  • return [max, min, drop] What are max, min and drop?
    – Wais Kamal
    Nov 26 at 12:42










  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?
    – yossico
    Nov 26 at 12:42

















up vote
8
down vote

favorite
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




















  • 1




    When you say drop, do you mean difference?
    – cmprogram
    Nov 26 at 12:40










  • @cmprogram, I mean the biggest delta between max an min.
    – Pommesloch
    Nov 26 at 12:41








  • 1




    is this array sorted? what do you mean by saying drop?
    – yossico
    Nov 26 at 12:41










  • return [max, min, drop] What are max, min and drop?
    – Wais Kamal
    Nov 26 at 12:42










  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?
    – yossico
    Nov 26 at 12:42















up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






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 at 13:20

























asked Nov 26 at 12:36









Pommesloch

19310




19310








  • 1




    When you say drop, do you mean difference?
    – cmprogram
    Nov 26 at 12:40










  • @cmprogram, I mean the biggest delta between max an min.
    – Pommesloch
    Nov 26 at 12:41








  • 1




    is this array sorted? what do you mean by saying drop?
    – yossico
    Nov 26 at 12:41










  • return [max, min, drop] What are max, min and drop?
    – Wais Kamal
    Nov 26 at 12:42










  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?
    – yossico
    Nov 26 at 12:42
















  • 1




    When you say drop, do you mean difference?
    – cmprogram
    Nov 26 at 12:40










  • @cmprogram, I mean the biggest delta between max an min.
    – Pommesloch
    Nov 26 at 12:41








  • 1




    is this array sorted? what do you mean by saying drop?
    – yossico
    Nov 26 at 12:41










  • return [max, min, drop] What are max, min and drop?
    – Wais Kamal
    Nov 26 at 12:42










  • what would be the drop output to [100,110,120,70,60,50,90,300,200]?
    – yossico
    Nov 26 at 12:42










1




1




When you say drop, do you mean difference?
– cmprogram
Nov 26 at 12:40




When you say drop, do you mean difference?
– cmprogram
Nov 26 at 12:40












@cmprogram, I mean the biggest delta between max an min.
– Pommesloch
Nov 26 at 12:41






@cmprogram, I mean the biggest delta between max an min.
– Pommesloch
Nov 26 at 12:41






1




1




is this array sorted? what do you mean by saying drop?
– yossico
Nov 26 at 12:41




is this array sorted? what do you mean by saying drop?
– yossico
Nov 26 at 12:41












return [max, min, drop] What are max, min and drop?
– Wais Kamal
Nov 26 at 12:42




return [max, min, drop] What are max, min and drop?
– Wais Kamal
Nov 26 at 12:42












what would be the drop output to [100,110,120,70,60,50,90,300,200]?
– yossico
Nov 26 at 12:42






what would be the drop output to [100,110,120,70,60,50,90,300,200]?
– yossico
Nov 26 at 12:42














6 Answers
6






active

oldest

votes

















up vote
6
down vote













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






























    up vote
    2
    down vote













    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




























      up vote
      2
      down vote













      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 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 at 13:55




















      up vote
      0
      down vote













      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 at 13:37










      • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
        – kakamg0
        Nov 26 at 13:56


















      up vote
      0
      down vote













      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






























        up vote
        -1
        down vote













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








        up vote
        6
        down vote













        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



























          up vote
          6
          down vote













          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

























            up vote
            6
            down vote










            up vote
            6
            down vote









            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 at 15:39

























            answered Nov 26 at 13:56









            Ted Hopp

            198k40309418




            198k40309418
























                up vote
                2
                down vote













                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

























                  up vote
                  2
                  down vote













                  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























                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    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 at 13:39









                    גלעד ברקן

                    11.9k21439




                    11.9k21439






















                        up vote
                        2
                        down vote













                        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 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 at 13:55

















                        up vote
                        2
                        down vote













                        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 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 at 13:55















                        up vote
                        2
                        down vote










                        up vote
                        2
                        down vote









                        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 at 15:16

























                        answered Nov 26 at 13:36









                        Salman A

                        172k65330416




                        172k65330416












                        • This fails for [100, 90, 80, 120, 200, 100 ,90]. The return must be max = 200, min = 90 and drop = 110
                          – Pommesloch
                          Nov 26 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 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 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 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 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 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 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 at 13:55












                        up vote
                        0
                        down vote













                        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 at 13:37










                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                          – kakamg0
                          Nov 26 at 13:56















                        up vote
                        0
                        down vote













                        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 at 13:37










                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                          – kakamg0
                          Nov 26 at 13:56













                        up vote
                        0
                        down vote










                        up vote
                        0
                        down vote









                        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 at 13:55

























                        answered Nov 26 at 13:34









                        kakamg0

                        79139




                        79139












                        • 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 at 13:37










                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                          – kakamg0
                          Nov 26 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 at 13:37










                        • @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                          – kakamg0
                          Nov 26 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 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 at 13:37












                        @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                        – kakamg0
                        Nov 26 at 13:56




                        @TedHopp Fixed it, I was excluding the last element when searching for the minimum value. Thanks!
                        – kakamg0
                        Nov 26 at 13:56










                        up vote
                        0
                        down vote













                        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



























                          up vote
                          0
                          down vote













                          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

























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            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 at 16:17

























                            answered Nov 26 at 14:12









                            Me.Name

                            10k22039




                            10k22039






















                                up vote
                                -1
                                down vote













                                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 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 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 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 at 13:34















                                up vote
                                -1
                                down vote













                                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 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 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 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 at 13:34













                                up vote
                                -1
                                down vote










                                up vote
                                -1
                                down vote









                                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 at 13:01

























                                answered Nov 26 at 12:50









                                cmprogram

                                991519




                                991519












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





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • 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

                                AnyDesk - Fatal Program Failure

                                How to calibrate 16:9 built-in touch-screen to a 4:3 resolution?

                                QoS: MAC-Priority for clients behind a repeater