首页 > 解决方案 > 试图找到一种方法来重构我的函数以使其更高效

问题描述

我有这个函数,如下所示,它根据长度参数对一组数字进行分组。长度表示每个子数组的最大长度。我想弄清楚的是,我可以采取一种方法来x => x % 2从结果变量的声明中转移到函数中。我唯一能想到的就是回调,但我不确定我该怎么做。对此的任何帮助表示赞赏,如果您发现任何其他冗余代码,请告诉我。

function myFunc(arr, length, fnc) {
  groups = []; 
  result  = [];
  for (let val of arr) {
    x = fnc(val);
    if (!groups[x]) {
      groups[x] = [];
    }
    if (!groups[x].length) {
      result .push(groups[x]);
    }
    groups[x].push(val);
    if (groups[x].length === length) {
      groups[x] = [];
    }
  }
  return result ;
}
//examples
const result1 = myFunc([1, 2, 3, 4], 2, x => x % 2)
console.log(result1) //[[1, 3], [2, 4]]

const result2 = myFunc([1, 2, 3, 4, 5, 6, 7], 4, x => x % 2)
console.log(result2) //[[1, 3, 5, 7], [2, 4, 6]]

const result3 = myFunc([1, 2, 3, 4, 5], 1, x => x % 2)
console.log(result3) //[[1], [2], [3], [4], [5]]

const result4 = myFunc([1, 2, 3, 4, 5, 6], 4, x => x % 2)
console.log(result4) //[[1, 3, 5], [2, 4, 6]]

我想实现的只是需要调用数组和我想创建的子数组的大小。只是对正在发生的事情的简要了解,这些数组的基础是查看它们是否可以将完整的数组制作为“长度”的大小,并且任何溢出都会被推送到另一个子数组。一个示例如下所示:

console.log(myfunc([1,2,3,4,5,6,7,8,9,10],3)) 

这将返回[[1,3,5][2,4,6][7,9][8,10]]

因此,如果有人可以帮助我从 console.log 语句中删除 fnc 参数并将其放入函数中,那将非常有帮助

标签: javascriptarraysfunctioncallbackrefactoring

解决方案


您遇到的问题是您知道此参数将始终相同,因此无需每次都编写它;它可以被烘焙到函数中。

在最简单的情况下,您可以直接从fnc参数列表中取出并手动将其声明为变量,始终将其设置为相同的值:

function myFunc(arr, length) {
  let fnc = x => x % 2;
  groups = []; 
  result  = [];
  for (let val of arr) {
    x = fnc(val);
    if (!groups[x]) {
      groups[x] = [];
    }
    if (!groups[x].length) {
      result .push(groups[x]);
    }
    groups[x].push(val);
    if (groups[x].length === length) {
      groups[x] = [];
    }
  }
  return result ;
}

//examples
const result1 = myFunc([1, 2, 3, 4], 2)
console.log(result1) //[[1, 3], [2, 4]]

const result2 = myFunc([1, 2, 3, 4, 5, 6, 7], 4)
console.log(result2) //[[1, 3, 5, 7], [2, 4, 6]]

const result3 = myFunc([1, 2, 3, 4, 5], 1)
console.log(result3) //[[1], [2], [3], [4], [5]]

const result4 = myFunc([1, 2, 3, 4, 5, 6], 4)
console.log(result4) //[[1, 3, 5], [2, 4, 6]]

在这一点上,实际上几乎没有任何意义fnc成为一个函数。每次都是一样的操作。只需执行该操作并将其粘贴到函数调用的位置即可。此外,您应该始终使用letorconst来声明事物,不要只为它们分配没有声明关键字 - 这会使它们成为全局变量,并且它们可能会以意想不到的方式与您的全局命名空间交互。最后,我敦促您将您的函数重命名为描述其功能的名称。这有助于每个阅读您的代码的人更直观地理解它,包括您未来的自己。

这就是一切的样子:

function splitArray(arr, length) {
  let groups = []; 
  let result = [];
  for (let val of arr) {
    let x = val % 2; //this does the same thing
    if (!groups[x]) {
      groups[x] = [];
    }
    if (!groups[x].length) {
      result.push(groups[x]);
    }
    groups[x].push(val);
    if (groups[x].length === length) {
      groups[x] = [];
    }
  }
  return result;
}

//examples
const result1 = splitArray([1, 2, 3, 4], 2)
console.log(result1) //[[1, 3], [2, 4]]

const result2 = splitArray([1, 2, 3, 4, 5, 6, 7], 4)
console.log(result2) //[[1, 3, 5, 7], [2, 4, 6]]

const result3 = splitArray([1, 2, 3, 4, 5], 1)
console.log(result3) //[[1], [2], [3], [4], [5]]

const result4 = splitArray([1, 2, 3, 4, 5, 6], 4)
console.log(result4) //[[1, 3, 5], [2, 4, 6]]


推荐阅读