Get the biggest chronological drop, min and max from an array with O(n)
up vote
8
down vote
favorite
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
javascript arrays algorithm calculation
|
show 11 more comments
up vote
8
down vote
favorite
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
javascript arrays algorithm calculation
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
|
show 11 more comments
up vote
8
down vote
favorite
up vote
8
down vote
favorite
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
javascript arrays algorithm calculation
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
javascript arrays algorithm calculation
javascript arrays algorithm calculation
edited Nov 26 at 13:20
asked Nov 26 at 12:36
Pommesloch
19510
19510
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
|
show 11 more comments
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
|
show 11 more comments
6 Answers
6
active
oldest
votes
up vote
6
down vote
accepted
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.
add a comment |
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.
add a comment |
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:
- Reset it every time the value increases w.r.t. previous value
- 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]));
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
add a comment |
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]))
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
add a comment |
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]));
add a comment |
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
accepted
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.
add a comment |
up vote
6
down vote
accepted
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.
add a comment |
up vote
6
down vote
accepted
up vote
6
down vote
accepted
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.
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]))
edited Nov 26 at 15:39
answered Nov 26 at 13:56
Ted Hopp
198k41311421
198k41311421
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 26 at 13:39
גלעד ברקן
12k21439
12k21439
add a comment |
add a comment |
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:
- Reset it every time the value increases w.r.t. previous value
- 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]));
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
add a comment |
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:
- Reset it every time the value increases w.r.t. previous value
- 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]));
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
add a comment |
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:
- Reset it every time the value increases w.r.t. previous value
- 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]));
You need to iterate the array once (O(n)
) and keep a running count of min and max values and:
- Reset it every time the value increases w.r.t. previous value
- 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]));
edited Nov 26 at 15:16
answered Nov 26 at 13:36
Salman A
174k66334421
174k66334421
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
add a comment |
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
add a comment |
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]))
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
add a comment |
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]))
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
add a comment |
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]))
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]))
edited Nov 26 at 13:55
answered Nov 26 at 13:34
kakamg0
82649
82649
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
add a comment |
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
add a comment |
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]));
add a comment |
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]));
add a comment |
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]));
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]));
edited Nov 26 at 16:17
answered Nov 26 at 14:12
Me.Name
10.1k22039
10.1k22039
add a comment |
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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];
}
edited Nov 26 at 13:01
answered Nov 26 at 12:50
cmprogram
1,063519
1,063519
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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