简体   繁体   English

如何提高函数的性能和可读性?

[英]How can I improve the performance and the readability of my function?

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.我最近不得不为求职面试做一个测试,提示是编写一个函数,在给定一组负数和正数的情况下,该函数返回最接近 0 的数字。

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:我的函数运行正常,但我从招聘人员那里听到说我的函数性能不是很好,可读性也不是很好,他们提到了以下问题:

  • Performances à double check (filter + sort + for + push + reserve + shift, 4 identical call to Math.abs)性能 à 双重检查(过滤器 + 排序 + for + 推送 + 保留 + 移位,对 Math.abs 的 4 次相同调用)
  • Lack of readability ( 4 if / else if)缺乏可读性(4 if / else if)

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:要求:

  • if the closest number in input could be either negative or positive, the function returns the positive one如果输入中最接近的数字可以是负数或正数,则函数返回正数
  • if the input array is undefined or empty, the function returns 0如果输入数组未定义或为空,则函数返回 0

when input is [8, 5, 10] the function returns 5当输入为 [8, 5, 10] 时,函数返回 5

when input is [5, 4, -9, 6, -10, -1, 8] the function returns -1当输入为 [5, 4, -9, 6, -10, -1, 8] 时,函数返回 -1

when input is [8, 2, 3, -2] the functions return 2当输入为 [8, 2, 3, -2] 时,函数返回 2

Although this isn't the best StackExchange forum for an "answer," Andreas does in fact give one.尽管这不是提供“答案”的最佳 StackExchange 论坛,但 Andreas 确实给出了答案。 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() (绝对值)函数当然是“数字与零的接近程度”的指标。 abs(-3) == 3 and so on. abs(-3) == 3等等。

Your function is indeed very complicated.你的函数确实很复杂。 You can make good use of the Math.abs function here to clean things up quite a bit.您可以充分利用这里的Math.abs函数来清理很多东西。 Here is a js implementation that I would have given这是我会给出的 js 实现

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.有可能招聘人员会找到一个使用reduce的解决方案也无法阅读。

But to extend on Andreas comment.但要扩展安德烈亚斯的评论。

Here's an example snippet with a function that uses reduce, comparing the absolute values or the sign.这是一个示例代码片段,其中包含一个使用 reduce 的函数,用于比较绝对值或符号。

 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]));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM