I recently had to do a test for a job interview, and the prompt was to code a function that returns the closest number to 0 given an array of negative and positive numbers.
My function works correctly but I heard back from the recruiter saying that my function is not very performant and and that the readability was not great, here are the problem that they mentioned:
I would like to know how I could have improved my function to make it more performant and more readable?
here's my function:
const closestToZero = (arr) => {
// 1-a variables:
let positiveNumbers = [];
let negativeNumbers = [];
// 1-b returns 0 if the input is either undefined or an empty array
if(typeof(arr) === 'undefined' || arr.length === 0) {
return 0
}
// 2- filter out non-number values then sort the array
const onlyNumbers = arr.filter(item => typeof(item) === 'number').sort((a,b) => a-b);
// 3- split the numbers into positive numbers and negative numbers
for(let i = 0; i < onlyNumbers.length; i++) {
if(onlyNumbers[i] > 0) {
positiveNumbers.push(onlyNumbers[i])
} else if (onlyNumbers[i] < 0) {
negativeNumbers.push(onlyNumbers[i])
}
}
// 4- reverse the negative array to get the closest to 0 at the first index
let reversedNegativeArray = negativeNumbers.reverse()
// 5- get rid of all the other values and keep only the closest to 0, if array empty return 0
let closestPositiveNumber = positiveNumbers.length > 0 ? positiveNumbers.shift() : 0
let closestNegativeNumber = reversedNegativeArray.length > 0 ? reversedNegativeArray.shift() : 0
// 6- Compare the result of the substraction of the closestPositiveNumber and the closestNegativeNumber to find the closestToZero
if(closestPositiveNumber - Math.abs(closestNegativeNumber) > 0 && closestNegativeNumber === 0 ) {
return closestPositiveNumber
} else if (closestPositiveNumber - Math.abs(closestNegativeNumber) < 0 && closestPositiveNumber === 0) {
return closestNegativeNumber
} else if(closestPositiveNumber - Math.abs(closestNegativeNumber) > 0) {
return closestNegativeNumber
} else if (closestPositiveNumber - Math.abs(closestNegativeNumber) <= 0) {
return closestPositiveNumber
}
}
requirements:
when input is [8, 5, 10] the function returns 5
when input is [5, 4, -9, 6, -10, -1, 8] the function returns -1
when input is [8, 2, 3, -2] the functions return 2
Although this isn't the best StackExchange forum for an "answer," Andreas does in fact give one. A solution might be like this: (pseudocode)
winner = 0 # arbitrarily assume the zeroth element is closest
for (i from 1 to array-length):
if abs(array[i]) < abs(array[winner]): # this one's closer ...
winner = i
The abs()
(absolute value) function is, of course, an indicator of "how close the number is to zero." abs(-3) == 3
and so on.
Your function is indeed very complicated. You can make good use of the Math.abs
function here to clean things up quite a bit. Here is a js implementation that I would have given
test = [-1, 5, 4, -9, 6, -10, -1, 8, 1];
function closeToZero(arr){
if(typeof(arr) === 'undefined' || arr.length === 0) {
return 0;
}
ret = test[0];
for(i = 1; i < test.length; i++){
if(Math.abs(ret) >= Math.abs(test[i]) ){
if(Math.abs(ret) == Math.abs(test[i])){
ret = Math.max(ret, test[i]);
}else{
ret = test[i];
}
}
}
return ret;
}
print(closeToZero(test));
Optionally you can also check for bad input if that was required
There's a possibility that the recruiter would have found a solution that uses reduce
also unreadable.
But to extend on Andreas comment.
Here's an example snippet with a function that uses reduce, comparing the absolute values or the sign.
const closestToZero = (arr) => { if(!arr || arr.length === 0) return 0; return arr.reduce((acc, x) => (Math.abs(x) < Math.abs(acc) || (Math.abs(x) === Math.abs(acc) && x > acc)) ? x : acc); } console.log(closestToZero()); console.log(closestToZero([])); console.log(closestToZero([8,5,10])); console.log(closestToZero([5, 4, -9, 6, -10, -1, 8])); console.log(closestToZero([8, -2, 3, 2]));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.