Skip to content

Commit c7d98df

Browse files
committed
Callback with right number of arguments.
1 parent 7b10e01 commit c7d98df

File tree

2 files changed

+97
-9
lines changed

2 files changed

+97
-9
lines changed

src/utils/array.js

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { format } from './string.js'
44
import { DimensionError } from '../error/DimensionError.js'
55
import { IndexError } from '../error/IndexError.js'
66
import { deepStrictEqual } from './object.js'
7+
import { findNumberOfArguments } from './optimizeCallback.js'
78

89
/**
910
* Calculate the size of a multi dimensional array.
@@ -835,13 +836,52 @@ export function get (array, index) {
835836
* @returns {*} The new array with each element being the result of the callback function.
836837
*/
837838
export function deepMap (value, array, callback) {
838-
return recurse(value, [], array, callback)
839-
function recurse (value, index, array, callback) {
839+
const numberOfArguments = findNumberOfArguments(callback, array)
840+
switch (numberOfArguments) {
841+
case 1:
842+
return recurse1(value)
843+
case 2:
844+
return recurse2(value, [])
845+
case 3:
846+
return recurse3(value, [])
847+
default:
848+
return recurse3(value, [])
849+
}
850+
851+
function recurse1 (value) {
852+
if (Array.isArray(value)) {
853+
return value.map(function (child) {
854+
// we create a copy of the index array and append the new index value
855+
const results = recurse1(child)
856+
return results
857+
})
858+
} else {
859+
// invoke the callback function with the right number of arguments
860+
return callback(value)
861+
}
862+
}
863+
864+
function recurse2 (value, index) {
840865
if (Array.isArray(value)) {
841866
return value.map(function (child, i) {
842867
// we create a copy of the index array and append the new index value
843868
index.push(i)
844-
const results = recurse(child, index, array, callback)
869+
const results = recurse2(child, index)
870+
index.pop()
871+
return results
872+
})
873+
} else {
874+
// invoke the callback function with the right number of arguments
875+
return callback(value, [...index])
876+
}
877+
}
878+
879+
function recurse3 (value, index) {
880+
if (Array.isArray(value)) {
881+
return value.map(function (child, i) {
882+
// we create a copy of the index array and append the new index value
883+
index.push(i)
884+
const results = recurse3(child, index)
845885
index.pop()
846886
return results
847887
})
@@ -862,13 +902,51 @@ export function deepMap (value, array, callback) {
862902
* @returns {*} The new array with each element being the result of the callback function.
863903
*/
864904
export function deepForEach (value, array, callback) {
865-
recurse(value, [], array, callback)
866-
function recurse (value, index, array, callback) {
905+
const numberOfArguments = findNumberOfArguments(callback, array)
906+
switch (numberOfArguments) {
907+
case 1:
908+
recurse1(value)
909+
break
910+
case 2:
911+
recurse2(value, [])
912+
break
913+
case 3:
914+
recurse3(value, [])
915+
break
916+
default:
917+
recurse3(value, [])
918+
break
919+
}
920+
921+
function recurse1 (value) {
922+
if (Array.isArray(value)) {
923+
return value.forEach(function (child) {
924+
recurse1(child)
925+
})
926+
} else {
927+
// invoke the callback function with the right number of arguments
928+
callback(value)
929+
}
930+
}
931+
932+
function recurse2 (value, index) {
933+
if (Array.isArray(value)) {
934+
return value.forEach(function (child, i) {
935+
index.push(i)
936+
recurse2(child, index)
937+
index.pop()
938+
})
939+
} else {
940+
// invoke the callback function with the right number of arguments
941+
callback(value, [...index])
942+
}
943+
}
944+
945+
function recurse3 (value, index) {
867946
if (Array.isArray(value)) {
868947
return value.forEach(function (child, i) {
869-
// we create a copy of the index array and append the new index value
870948
index.push(i)
871-
recurse(child, index, array, callback)
949+
recurse3(child, index)
872950
index.pop()
873951
})
874952
} else {

src/utils/optimizeCallback.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function optimizeCallback (callback, array, name) {
1515
const firstIndex = (array.isMatrix ? array.size() : arraySize(array)).map(() => 0)
1616
const firstValue = array.isMatrix ? array.get(firstIndex) : get(array, firstIndex)
1717
const hasSingleSignature = Object.keys(callback.signatures).length === 1
18-
const numberOfArguments = findNumberOfArguments(callback, firstValue, firstIndex, array)
18+
const numberOfArguments = _typedFindNumberOfArguments(callback, firstValue, firstIndex, array)
1919
const fastCallback = hasSingleSignature ? Object.values(callback.signatures)[0] : callback
2020
if (numberOfArguments >= 1 && numberOfArguments <= 3) {
2121
return (...args) => tryFunctionWithArgs(fastCallback, args.slice(0, numberOfArguments), name, callback.name)
@@ -25,7 +25,17 @@ export function optimizeCallback (callback, array, name) {
2525
return callback
2626
}
2727

28-
export function findNumberOfArguments (callback, value, index, array) {
28+
export function findNumberOfArguments (callback, array) {
29+
if (typed.isTypedFunction(callback)) {
30+
const firstIndex = (array.isMatrix ? array.size() : arraySize(array)).map(() => 0)
31+
const firstValue = array.isMatrix ? array.get(firstIndex) : get(array, firstIndex)
32+
return _typedFindNumberOfArguments(callback, firstValue, firstIndex, array)
33+
} else {
34+
return callback.length
35+
}
36+
}
37+
38+
function _typedFindNumberOfArguments (callback, value, index, array) {
2939
const testArgs = [value, index, array]
3040
for (let i = 3; i > 0; i--) {
3141
const args = testArgs.slice(0, i)

0 commit comments

Comments
 (0)