'use strict'
const reduce = (arr, func, initialValue) => {
let acc = initialValue
let arrCopy = arr
if(initialValue === undefined) {
acc = arr[0]
arrCopy = arr.slice(1)
}
for(var i = 0; i < arrCopy.length; i++){
acc = func(acc, arrCopy[i], i, arrCopy)
}
return acc
}
export default reduce
const reduce = (arr, func, initialValue) => {
let acc = initialValue
let arrCopy = arr
if(initialValue === undefined) {
acc = arr[0]
arrCopy = arr.slice(1)
}
return (function reduceInternal (accInternal, arrInternal, counter) {
const [head, ...tail] = arrInternal
return arrInternal.lenghth === 0
? accInternal
: reduceInternal(func(accInternal, head, counter, arrCopy), tail, counter + 1)
})(acc, arrCopy, 0)
}
return (function reduceInternal (accInternal, arrInternal, counter) {
- passando aqui os valores inicias de todos os parametros que serão modificados
const [head, ...tail] = arrInternal
- cabeça e cauda que vão pegar no array interno
reduceInternal(func(accInternal, head, counter, arrCopy), tail, counter + 1)
- Chamada recursiva da função passando uma função com os seguintes argumentos - acumulador, primeiro item do array, contador, array inicial (copia do array menos o primeiro item) e outros argumentos da função recursiva que são restante do array, contador
})(acc, arrCopy, 0)
- acumulador, cópia do array, indice da iteração
Vamos aproveitar também para remover a mutabilidade de código
Aqui estamos removendo a mutabilidade do código que é feita na alteração do valores dentro do IF. O quanto mais deixarmos nosso código não mutável melhor, resolvemos isso criando a constante e já iniciando o nosso método com os valores setados que precisamos.
A função isInitialValueUndefined
foi criada fora do método reduce para otimizarmos o nosso código. Se ela fosse criada dentro teriamos uma má performance pelo fato de toda vez que fosse executado o método reduce ela seria criada novamente. Da forma que está nos temos uma refêrencia para a função e não temos também uma concorrência com outras fuções
Antes:
let acc = initialValue
let arrCopy = arr
if(initialValue === undefined) {
acc = arr[0]
arrCopy = arr.slice(1)
}
Depois:
const isInitialValueUndefined = (initialValue) => initialValue === undefined
const reduce = (arr, func, initialValue) => {
const acc = isInitialValueUndefined(initialValue) ? arr[0] : initialValue
const arrCopy = isInitialValueUndefined(initialValue) ? arr.slice(1) : arr
Criamos agora uma função accNext
para removermos a chamada que está muito grande no método. Lembre-se que esse método está funcionando por quê está retornando uma função. Caso estivesse sendo só declarada a função dentro da variável seria executada duas vezes o nosso código e o resultado dessa função seria atribuida a essa variável accNext
.
Antes:
return arrInternal.lenghth === 0
? accInternal
: reduceInternal(func(accInternal, head, counter, arrCopy), tail, counter + 1)
})(acc, arrCopy, 0)
Depois:
return (function reduceInternal (accInternal, arrInternal, counter) {
const [head, ...tail] = arrInternal
const accNext = () => func(accInternal, head, counter, arrCopy)
return arrInternal.length === 0
? accInternal
: reduceInternal(accNext, tail, counter + 1)
})(acc, arrCopy, 0)
'use strict'
const reduce = (arr, func, initialValue) => {
let acc = initialValue
let arrCopy = arr
if(initialValue === undefined) {
acc = arr[0]
arrCopy = arr.slice(1)
}
for(var i = 0; i < arrCopy.length; i++){
acc = func(acc, arrCopy[i], i, arrCopy)
}
return acc
}
export default reduce