bha*_*rty 6 javascript arrays reduce
我正在尝试实现相当于在executeprogram.com上回答测验的.join()功能。我的代码通过了测试,但看起来很难看。我以丑陋的方式解决的具体问题是:构造的函数采用数组和分隔符作为参数,但在构造结果连接输出时,不应将分隔符插入到数组的最后一项之后。这意味着我必须测试,当使用 迭代数组时,我是否位于最后一项(以便我可以跳过使用分隔符)[哎呀:请参阅下面的注释]。如果数组中存在重复值,则使用or不起作用。所以我创建了一个计数器。我不喜欢它。我希望得到有关如何做得更好的建议。这是代码:.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;
}
},
'')
);
}
}
Run Code Online (Sandbox Code Playgroud)
测试及其预期输出如下。同样,上面的函数通过了所有测试,但我认为必须有更好的方法。
> 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: ''
Run Code Online (Sandbox Code Playgroud)
注意:在看到所有有用的答案后,我意识到这个丑陋代码的真正原因是我错误地认为分隔符位于项目“之后”。实际上,分隔符位于项目之间,如果将其插入除第一个项目之外的每个项目之前,则可以使其位于每个项目之间。那么你就不需要测试最后一项了。当您消除需要测试最后一项的假设时,一切都会变得简单得多。所以基本上,我一开始就把问题说错了。感谢大家的回答!
使用 4 个参数调用reduce 回调:
arr.reduce(callback( accumulator, currentValue, index, array)
Run Code Online (Sandbox Code Playgroud)
例子:
arr.reduce(callback( accumulator, currentValue, index, array)
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式缩短代码:
'')。i) 以 0 开头,因此您可以跳过第一项的分隔符(0 被转换为false)。这允许您跳过三元中的比较。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([], ','))Run Code Online (Sandbox Code Playgroud)
更改顺序时的另一个想法(基于@JCFordarr[0]想法)是解构数组,获取第一个元素(first),如果它为空则为其分配默认值。然后减少数组的其余部分,并用作first初始值。
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([], ','))Run Code Online (Sandbox Code Playgroud)
正如其他人指出的那样,您可以在回调中使用索引和数组参数。
但还有另一种方法。您不必知道何时遇到最后一个数组元素。您已经知道第一个元素是什么,并且可以使用它。
const join = (arr, sep=',') => arr.slice(1).reduce((acc, item) => acc + sep + item, arr[0]);
Run Code Online (Sandbox Code Playgroud)
为了进一步完善该函数,请利用很少使用的累加器默认初始值。如果不将初始值传递给reduce()函数,则第一次执行回调时将获得数组的第一个和第二个元素。
const join = (arr, sep=',') => arr.reduce((acc, item) => acc + sep + item);
Run Code Online (Sandbox Code Playgroud)
并处理空数组而不会出现错误......
const join = (arr, sep=',') => arr[0] ? arr.reduce((acc, item) => acc + sep + item) : '';
Run Code Online (Sandbox Code Playgroud)