为了账号安全,请及时绑定邮箱和手机立即绑定

测试在 Javascript 中使用 reduce() 时是否到达数组的最后一项

测试在 Javascript 中使用 reduce() 时是否到达数组的最后一项

一只萌萌小番薯 2023-04-20 10:45:17
我正在尝试实现相当于.join()使用来回答executeprogram.com.reduce()上的测验。我的代码通过了测试,但看起来很难看。我以丑陋的方式解决的具体问题是:构造的函数将一个数组和一个分隔符作为参数,但是在构造结果连接输出时,不应在数组的最后一项之后插入分隔符。这意味着我必须测试,当使用迭代数组时,我是否在最后一项(这样我就可以跳过使用分隔符)[糟糕:见下面的注释]。使用或join()reduce()indexOflastIndexOf如果数组中有重复值,则不起作用。所以我创建了一个计数器。我不喜欢它。我很乐意提供有关如何更好地做到这一点的建议。这是代码: function join(arr, separator) {  let counter = 0;  if (arr.length === 0) { return(''); }  else {     return (    arr.reduce((accumulator, item) =>      {        if (counter === arr.length - 1) {          return accumulator + item;        } else {          counter += 1;           return accumulator + item + separator;        }      },       '')    );  }} 测试及其预期输出如下。同样,上面的函数通过了所有测试,但我认为必须有更好的方法。> join(['a'], ',')Expected: 'a'> join(['a', 'b'], ',')Expected: 'a,b' > join(['a', 'b', 'c'], '')Expected: 'abc'> join(['a', 'b', 'c', 'd'], 'x')Expected: 'axbxcxd'> join(['a', 'b'], 'COMMA')Expected: 'aCOMMAb'> join(['', '', ''], ',')Expected: ',,'> join([], ',')Expected: ''注意:在看到所有有用的答案后,我意识到这个丑陋代码的真正原因是我错误地假设分隔符出现在一个项目“之后”。实际上,分隔符位于项目之间,如果将其插入除第一个项目之外的每个项目之前,则可以使其位于每个项目之间。那么你不需要测试最后一项。当您删除需要测试最后一项的假设时,一切都会简单得多。所以基本上,我一开始就把问题说错了。感谢大家的回答!
查看完整描述

4 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

使用 4 个参数调用 reduce 回调:


arr.reduce(callback( accumulator, currentValue, index, array)

例子:


function join(arr, separator) {

  if (arr.length === 0) { return(''); }

  

  else { 

    return (

    arr.reduce((accumulator, item, counter) =>

      {

        if (counter === arr.length - 1) {

          return accumulator + item;

        } else {

          counter += 1; 

          return accumulator + item + separator;

        }

      }, 

      '')

    );

  }

}

    

    

console.log(join(['a'], ','))

console.log(join(['a', 'b'], ','))

console.log(join(['a', 'b', 'c'], ''))

console.log(join(['a', 'b', 'c', 'd'], 'x'))

console.log(join(['a', 'b'], 'COMMA'))

console.log(join(['', '', ''], ','))

console.log(join([], ','))

您可以通过以下方式稍微缩短代码:

  1. 跳过空检查 - 如果数组为空,reduce 将返回初始值 ( '')。

  2. 使用模板字符串和三元组。如果它不是最后一项,则添加分隔符,如果是,则使用空字符串。

  3. 由于计数器 ( i) 以 0 开头,您可以跳过第一项的分隔符(0 转换为false)。这允许您跳过三元中的比较。

const join = (arr, separator) => arr.reduce((accumulator, item, i) =>

  `${accumulator}${i ? separator : ''}${item}`

, '')

    

    

console.log(join(['a'], ','))

console.log(join(['a', 'b'], ','))

console.log(join(['a', 'b', 'c'], ''))

console.log(join(['a', 'b', 'c', 'd'], 'x'))

console.log(join(['a', 'b'], 'COMMA'))

console.log(join(['', '', ''], ','))

console.log(join([], ','))


更改顺序时的另一个想法(基于@JCFord 的arr[0]想法)是解构数组,获取第一个元素 ( first),如果它为空,则为其分配默认值。然后减少数组的其余部分,并用作first初始值。


const join = ([first = '', ...arr], separator) => 

  arr.reduce((accumulator, item, i) => `${accumulator}${separator}${item}`, first)

    

    

console.log(join(['a'], ','))

console.log(join(['a', 'b'], ','))

console.log(join(['a', 'b', 'c'], ''))

console.log(join(['a', 'b', 'c', 'd'], 'x'))

console.log(join(['a', 'b'], 'COMMA'))

console.log(join(['', '', ''], ','))

console.log(join([], ','))


查看完整回答
反对 回复 2023-04-20
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

正如其他人指出的那样,您可以在回调中使用索引和数组参数。

但还有另一种方法。您不必知道何时遇到最后一个数组元素。您已经知道第一个元素是什么,您可以直接使用它。

const join = (arr, sep=',') => arr.slice(1).reduce((acc, item) => acc + sep + item, arr[0]);

要进一步细化函数,请利用累加器很少使用的默认初始值。如果您没有将初始值传递给 reduce() 函数,则回调的第一次执行将获得数组的第一个和第二个元素。

const join = (arr, sep=',') => arr.reduce((acc, item) => acc + sep + item);

并无误地处理空数组......

const join = (arr, sep=',') => arr[0] ? arr.reduce((acc, item) => acc + sep + item) : '';



查看完整回答
反对 回复 2023-04-20
?
月关宝盒

TA贡献1772条经验 获得超5个赞

我是这样做的。


假设您想用逗号分隔此数组,但以句点结尾。


let names = ['Amber', 'Bobby', 'Chris', 'Dennis', 'Edward'];

您可以使用第三个索引参数“i”并将其作为变量与要减少的数组的长度进行比较。


names.reduce((a, c, i) => {

   const isLast = i == names.length -1;

   return `${a}${c}` + (isLast ? '.' : ', '); 

}, "")

结果: 'Amber, Bobby, Chris, Dennis, Edward.'


查看完整回答
反对 回复 2023-04-20
?
FFIVE

TA贡献1797条经验 获得超6个赞

您可以通过从 中删除初始值来简化当前函数reduce。然后这将使用第一个元素作为初始值。您已经设置了一个保护子句来处理空数组,因此在这方面您应该没问题。

function join(arr, separator) {

  if (arr.length == 0) return '';

  return arr.reduce((accumulator, item) => accumulator + separator + item);

}


console.log(join(['a'], ','))

console.log(join(['a', 'b'], ','))

console.log(join(['a', 'b', 'c'], ''))

console.log(join(['a', 'b', 'c', 'd'], 'x'))

console.log(join(['a', 'b'], 'COMMA'))

console.log(join(['', '', ''], ','))

console.log(join([], ','))


join使用字符串数组的另一种简单方法reduce是根本不关心它产生的额外分隔符,并slice在减少数组后将其关闭。


function join(arr, separator) {

  return arr.reduce((accumulator, item) => accumulator + separator + item, '')

            .slice(separator.length);

}


console.log(join(['a'], ','))

console.log(join(['a', 'b'], ','))

console.log(join(['a', 'b', 'c'], ''))

console.log(join(['a', 'b', 'c', 'd'], 'x'))

console.log(join(['a', 'b'], 'COMMA'))

console.log(join(['', '', ''], ','))

console.log(join([], ','))



查看完整回答
反对 回复 2023-04-20
  • 4 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信