Why does passing in a number as a string into an array cause the wrong result?
I have built a function that allows you to pass through an array and it successfully returns the second highest and second lowest numbers. However, I'm new to error handling and don't understand why this fails:
getNos([5,"5",8]);
It works correctly when passing in getNos([5,5,8])
; or passing arrays like getNos(["5",8]);
.
Can someone explain what's happening here and how to fix it? Thanks for any help here - the function code is below:
function getNos(arr){
if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
throw 'Invalid Input';
} else {
var result;
var uniqueVals = Array.from(new Set(arr));
var highest = highestVal(arr);
var lowest = lowestVal(arr);
if (uniqueVals.length == 1) {
result = arr[0] + " " + arr[0];
} else if (arr.length == 2 || uniqueVals.length == 2) {
result = highest + " " + lowest;
} else {
arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
var secondHighest = highestVal(arr);
var secondLowest = lowestVal(arr);
if (arr.length == 1) {
arr = arr.slice(arr.indexOf(secondHighest));
result = highestVal(arr);
} else {
result = secondLowest + " " + secondHighest;
}
}
return result;
}
function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}
javascript
add a comment |
I have built a function that allows you to pass through an array and it successfully returns the second highest and second lowest numbers. However, I'm new to error handling and don't understand why this fails:
getNos([5,"5",8]);
It works correctly when passing in getNos([5,5,8])
; or passing arrays like getNos(["5",8]);
.
Can someone explain what's happening here and how to fix it? Thanks for any help here - the function code is below:
function getNos(arr){
if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
throw 'Invalid Input';
} else {
var result;
var uniqueVals = Array.from(new Set(arr));
var highest = highestVal(arr);
var lowest = lowestVal(arr);
if (uniqueVals.length == 1) {
result = arr[0] + " " + arr[0];
} else if (arr.length == 2 || uniqueVals.length == 2) {
result = highest + " " + lowest;
} else {
arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
var secondHighest = highestVal(arr);
var secondLowest = lowestVal(arr);
if (arr.length == 1) {
arr = arr.slice(arr.indexOf(secondHighest));
result = highestVal(arr);
} else {
result = secondLowest + " " + secondHighest;
}
}
return result;
}
function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}
javascript
1
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
1
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45
add a comment |
I have built a function that allows you to pass through an array and it successfully returns the second highest and second lowest numbers. However, I'm new to error handling and don't understand why this fails:
getNos([5,"5",8]);
It works correctly when passing in getNos([5,5,8])
; or passing arrays like getNos(["5",8]);
.
Can someone explain what's happening here and how to fix it? Thanks for any help here - the function code is below:
function getNos(arr){
if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
throw 'Invalid Input';
} else {
var result;
var uniqueVals = Array.from(new Set(arr));
var highest = highestVal(arr);
var lowest = lowestVal(arr);
if (uniqueVals.length == 1) {
result = arr[0] + " " + arr[0];
} else if (arr.length == 2 || uniqueVals.length == 2) {
result = highest + " " + lowest;
} else {
arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
var secondHighest = highestVal(arr);
var secondLowest = lowestVal(arr);
if (arr.length == 1) {
arr = arr.slice(arr.indexOf(secondHighest));
result = highestVal(arr);
} else {
result = secondLowest + " " + secondHighest;
}
}
return result;
}
function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}
javascript
I have built a function that allows you to pass through an array and it successfully returns the second highest and second lowest numbers. However, I'm new to error handling and don't understand why this fails:
getNos([5,"5",8]);
It works correctly when passing in getNos([5,5,8])
; or passing arrays like getNos(["5",8]);
.
Can someone explain what's happening here and how to fix it? Thanks for any help here - the function code is below:
function getNos(arr){
if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
throw 'Invalid Input';
} else {
var result;
var uniqueVals = Array.from(new Set(arr));
var highest = highestVal(arr);
var lowest = lowestVal(arr);
if (uniqueVals.length == 1) {
result = arr[0] + " " + arr[0];
} else if (arr.length == 2 || uniqueVals.length == 2) {
result = highest + " " + lowest;
} else {
arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
var secondHighest = highestVal(arr);
var secondLowest = lowestVal(arr);
if (arr.length == 1) {
arr = arr.slice(arr.indexOf(secondHighest));
result = highestVal(arr);
} else {
result = secondLowest + " " + secondHighest;
}
}
return result;
}
function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}
javascript
javascript
asked Nov 19 '18 at 15:36
user8758206user8758206
453110
453110
1
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
1
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45
add a comment |
1
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
1
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45
1
1
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
1
1
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45
add a comment |
3 Answers
3
active
oldest
votes
Follow carefully the logic var uniqueVals = Array.from(new Set(arr))
. What will this line return when you have arrays such as [5,"5",8]
vs [5,5,8]
vs ["5", 8]
?
A Set
stores unique value of a type
. "5"
is of type string
whereas 5 is of type number
. The highestVal
and lowestVal
functions can compare "5"
and 8
, no problem, but since an array could include either a string
or number
for either 5 or 8 as well, then you will get funny values being returned.
To fix this, before passing arr
to the Set
, you need to convert all values to a single type, preferably number
.
let numberArr = arr.map(el=>+el)
is one way of doing that, but you may want better data validation than that.
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
add a comment |
Simple fix would be map the values to numbers before creating the set to avoid having the same numeric values as both string and number in the set
Change
var uniqueVals = Array.from(new Set(arr));
To
var uniqueVals = Array.from(new Set(arr.map(Number)));
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you passgetNos([5,"4",8])
? I don't think that's what OP was asking for...
– MrUpsidown
Nov 19 '18 at 15:52
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
|
show 1 more comment
The function does not fail in the sense that it throws an error. For these types of questions please add an example of "expected results".
When you compare strings and numbers in JavaScript, you are relying on implicit coercion to take care of the comparison. In this case it won't throw and error and break anything, it is fine as JavaScript will convert your string to a number and compare (unless its a strict equality === which checks type as well).
Should the result be based off what was passed in? Or after the input has been filtered for numbers only. Or if the input can be converted to valid numbers?
In the case of filter for valid numbers. Filter the input as follows...
arr = arr.filter(data => typeof data === 'number')
In the case of converting values to a number and removing those that cannot be converted...
arr = arr.reduce(((acc, el) => {
const num = Number(el);
if (!Number.isNaN(num)) acc.push(num);
return acc;
}), );
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',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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%2f53377992%2fwhy-does-passing-in-a-number-as-a-string-into-an-array-cause-the-wrong-result%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Follow carefully the logic var uniqueVals = Array.from(new Set(arr))
. What will this line return when you have arrays such as [5,"5",8]
vs [5,5,8]
vs ["5", 8]
?
A Set
stores unique value of a type
. "5"
is of type string
whereas 5 is of type number
. The highestVal
and lowestVal
functions can compare "5"
and 8
, no problem, but since an array could include either a string
or number
for either 5 or 8 as well, then you will get funny values being returned.
To fix this, before passing arr
to the Set
, you need to convert all values to a single type, preferably number
.
let numberArr = arr.map(el=>+el)
is one way of doing that, but you may want better data validation than that.
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
add a comment |
Follow carefully the logic var uniqueVals = Array.from(new Set(arr))
. What will this line return when you have arrays such as [5,"5",8]
vs [5,5,8]
vs ["5", 8]
?
A Set
stores unique value of a type
. "5"
is of type string
whereas 5 is of type number
. The highestVal
and lowestVal
functions can compare "5"
and 8
, no problem, but since an array could include either a string
or number
for either 5 or 8 as well, then you will get funny values being returned.
To fix this, before passing arr
to the Set
, you need to convert all values to a single type, preferably number
.
let numberArr = arr.map(el=>+el)
is one way of doing that, but you may want better data validation than that.
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
add a comment |
Follow carefully the logic var uniqueVals = Array.from(new Set(arr))
. What will this line return when you have arrays such as [5,"5",8]
vs [5,5,8]
vs ["5", 8]
?
A Set
stores unique value of a type
. "5"
is of type string
whereas 5 is of type number
. The highestVal
and lowestVal
functions can compare "5"
and 8
, no problem, but since an array could include either a string
or number
for either 5 or 8 as well, then you will get funny values being returned.
To fix this, before passing arr
to the Set
, you need to convert all values to a single type, preferably number
.
let numberArr = arr.map(el=>+el)
is one way of doing that, but you may want better data validation than that.
Follow carefully the logic var uniqueVals = Array.from(new Set(arr))
. What will this line return when you have arrays such as [5,"5",8]
vs [5,5,8]
vs ["5", 8]
?
A Set
stores unique value of a type
. "5"
is of type string
whereas 5 is of type number
. The highestVal
and lowestVal
functions can compare "5"
and 8
, no problem, but since an array could include either a string
or number
for either 5 or 8 as well, then you will get funny values being returned.
To fix this, before passing arr
to the Set
, you need to convert all values to a single type, preferably number
.
let numberArr = arr.map(el=>+el)
is one way of doing that, but you may want better data validation than that.
answered Nov 19 '18 at 15:46
wlhwlh
1,8261823
1,8261823
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
add a comment |
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
ahh I see... the logic is always right. thanks...
– user8758206
Nov 19 '18 at 16:07
add a comment |
Simple fix would be map the values to numbers before creating the set to avoid having the same numeric values as both string and number in the set
Change
var uniqueVals = Array.from(new Set(arr));
To
var uniqueVals = Array.from(new Set(arr.map(Number)));
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you passgetNos([5,"4",8])
? I don't think that's what OP was asking for...
– MrUpsidown
Nov 19 '18 at 15:52
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
|
show 1 more comment
Simple fix would be map the values to numbers before creating the set to avoid having the same numeric values as both string and number in the set
Change
var uniqueVals = Array.from(new Set(arr));
To
var uniqueVals = Array.from(new Set(arr.map(Number)));
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you passgetNos([5,"4",8])
? I don't think that's what OP was asking for...
– MrUpsidown
Nov 19 '18 at 15:52
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
|
show 1 more comment
Simple fix would be map the values to numbers before creating the set to avoid having the same numeric values as both string and number in the set
Change
var uniqueVals = Array.from(new Set(arr));
To
var uniqueVals = Array.from(new Set(arr.map(Number)));
Simple fix would be map the values to numbers before creating the set to avoid having the same numeric values as both string and number in the set
Change
var uniqueVals = Array.from(new Set(arr));
To
var uniqueVals = Array.from(new Set(arr.map(Number)));
edited Nov 19 '18 at 15:51
answered Nov 19 '18 at 15:45
charlietflcharlietfl
139k1387120
139k1387120
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you passgetNos([5,"4",8])
? I don't think that's what OP was asking for...
– MrUpsidown
Nov 19 '18 at 15:52
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
|
show 1 more comment
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you passgetNos([5,"4",8])
? I don't think that's what OP was asking for...
– MrUpsidown
Nov 19 '18 at 15:52
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Why? Would you care explaining what your code does and how it will fix OP's question?
– MrUpsidown
Nov 19 '18 at 15:48
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
Because String "5" and number 5 would create separate values in set
– charlietfl
Nov 19 '18 at 15:49
I see. What will happen then if you pass
getNos([5,"4",8])
? I don't think that's what OP was asking for...– MrUpsidown
Nov 19 '18 at 15:52
I see. What will happen then if you pass
getNos([5,"4",8])
? I don't think that's what OP was asking for...– MrUpsidown
Nov 19 '18 at 15:52
1
1
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
What's wrong with that case? uniqueVals would be [5,4,8]. All the values have to pass OP's isNan test
– charlietfl
Nov 19 '18 at 15:54
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
didn't realise it would be such a simple fix, thank you
– user8758206
Nov 19 '18 at 16:09
|
show 1 more comment
The function does not fail in the sense that it throws an error. For these types of questions please add an example of "expected results".
When you compare strings and numbers in JavaScript, you are relying on implicit coercion to take care of the comparison. In this case it won't throw and error and break anything, it is fine as JavaScript will convert your string to a number and compare (unless its a strict equality === which checks type as well).
Should the result be based off what was passed in? Or after the input has been filtered for numbers only. Or if the input can be converted to valid numbers?
In the case of filter for valid numbers. Filter the input as follows...
arr = arr.filter(data => typeof data === 'number')
In the case of converting values to a number and removing those that cannot be converted...
arr = arr.reduce(((acc, el) => {
const num = Number(el);
if (!Number.isNaN(num)) acc.push(num);
return acc;
}), );
add a comment |
The function does not fail in the sense that it throws an error. For these types of questions please add an example of "expected results".
When you compare strings and numbers in JavaScript, you are relying on implicit coercion to take care of the comparison. In this case it won't throw and error and break anything, it is fine as JavaScript will convert your string to a number and compare (unless its a strict equality === which checks type as well).
Should the result be based off what was passed in? Or after the input has been filtered for numbers only. Or if the input can be converted to valid numbers?
In the case of filter for valid numbers. Filter the input as follows...
arr = arr.filter(data => typeof data === 'number')
In the case of converting values to a number and removing those that cannot be converted...
arr = arr.reduce(((acc, el) => {
const num = Number(el);
if (!Number.isNaN(num)) acc.push(num);
return acc;
}), );
add a comment |
The function does not fail in the sense that it throws an error. For these types of questions please add an example of "expected results".
When you compare strings and numbers in JavaScript, you are relying on implicit coercion to take care of the comparison. In this case it won't throw and error and break anything, it is fine as JavaScript will convert your string to a number and compare (unless its a strict equality === which checks type as well).
Should the result be based off what was passed in? Or after the input has been filtered for numbers only. Or if the input can be converted to valid numbers?
In the case of filter for valid numbers. Filter the input as follows...
arr = arr.filter(data => typeof data === 'number')
In the case of converting values to a number and removing those that cannot be converted...
arr = arr.reduce(((acc, el) => {
const num = Number(el);
if (!Number.isNaN(num)) acc.push(num);
return acc;
}), );
The function does not fail in the sense that it throws an error. For these types of questions please add an example of "expected results".
When you compare strings and numbers in JavaScript, you are relying on implicit coercion to take care of the comparison. In this case it won't throw and error and break anything, it is fine as JavaScript will convert your string to a number and compare (unless its a strict equality === which checks type as well).
Should the result be based off what was passed in? Or after the input has been filtered for numbers only. Or if the input can be converted to valid numbers?
In the case of filter for valid numbers. Filter the input as follows...
arr = arr.filter(data => typeof data === 'number')
In the case of converting values to a number and removing those that cannot be converted...
arr = arr.reduce(((acc, el) => {
const num = Number(el);
if (!Number.isNaN(num)) acc.push(num);
return acc;
}), );
answered Nov 19 '18 at 16:25
Sunny WongSunny Wong
866
866
add a comment |
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.
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%2f53377992%2fwhy-does-passing-in-a-number-as-a-string-into-an-array-cause-the-wrong-result%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
What is the "wrong result" ?
– epascarello
Nov 19 '18 at 15:44
1
It works correctly when passing in [...] or passing arrays like [...]. So when does it not work?
– MrUpsidown
Nov 19 '18 at 15:45