Skip to content

Commit

Permalink
Callback with right number of arguments.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvd101x committed Sep 16, 2024
1 parent 7b10e01 commit c7d98df
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 9 deletions.
92 changes: 85 additions & 7 deletions src/utils/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { format } from './string.js'
import { DimensionError } from '../error/DimensionError.js'
import { IndexError } from '../error/IndexError.js'
import { deepStrictEqual } from './object.js'
import { findNumberOfArguments } from './optimizeCallback.js'

/**
* Calculate the size of a multi dimensional array.
Expand Down Expand Up @@ -835,13 +836,52 @@ export function get (array, index) {
* @returns {*} The new array with each element being the result of the callback function.
*/
export function deepMap (value, array, callback) {
return recurse(value, [], array, callback)
function recurse (value, index, array, callback) {
const numberOfArguments = findNumberOfArguments(callback, array)
switch (numberOfArguments) {
case 1:
return recurse1(value)
case 2:
return recurse2(value, [])
case 3:
return recurse3(value, [])
default:
return recurse3(value, [])
}

function recurse1 (value) {
if (Array.isArray(value)) {
return value.map(function (child) {
// we create a copy of the index array and append the new index value
const results = recurse1(child)
return results
})
} else {
// invoke the callback function with the right number of arguments
return callback(value)
}
}

function recurse2 (value, index) {
if (Array.isArray(value)) {
return value.map(function (child, i) {
// we create a copy of the index array and append the new index value
index.push(i)
const results = recurse(child, index, array, callback)
const results = recurse2(child, index)
index.pop()
return results
})
} else {
// invoke the callback function with the right number of arguments
return callback(value, [...index])
}
}

function recurse3 (value, index) {
if (Array.isArray(value)) {
return value.map(function (child, i) {
// we create a copy of the index array and append the new index value
index.push(i)
const results = recurse3(child, index)
index.pop()
return results
})
Expand All @@ -862,13 +902,51 @@ export function deepMap (value, array, callback) {
* @returns {*} The new array with each element being the result of the callback function.
*/
export function deepForEach (value, array, callback) {
recurse(value, [], array, callback)
function recurse (value, index, array, callback) {
const numberOfArguments = findNumberOfArguments(callback, array)
switch (numberOfArguments) {
case 1:
recurse1(value)
break
case 2:
recurse2(value, [])
break
case 3:
recurse3(value, [])
break
default:
recurse3(value, [])
break
}

function recurse1 (value) {
if (Array.isArray(value)) {
return value.forEach(function (child) {
recurse1(child)
})
} else {
// invoke the callback function with the right number of arguments
callback(value)
}
}

function recurse2 (value, index) {
if (Array.isArray(value)) {
return value.forEach(function (child, i) {
index.push(i)
recurse2(child, index)
index.pop()
})
} else {
// invoke the callback function with the right number of arguments
callback(value, [...index])
}
}

function recurse3 (value, index) {
if (Array.isArray(value)) {
return value.forEach(function (child, i) {
// we create a copy of the index array and append the new index value
index.push(i)
recurse(child, index, array, callback)
recurse3(child, index)
index.pop()
})
} else {
Expand Down
14 changes: 12 additions & 2 deletions src/utils/optimizeCallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function optimizeCallback (callback, array, name) {
const firstIndex = (array.isMatrix ? array.size() : arraySize(array)).map(() => 0)
const firstValue = array.isMatrix ? array.get(firstIndex) : get(array, firstIndex)
const hasSingleSignature = Object.keys(callback.signatures).length === 1
const numberOfArguments = findNumberOfArguments(callback, firstValue, firstIndex, array)
const numberOfArguments = _typedFindNumberOfArguments(callback, firstValue, firstIndex, array)
const fastCallback = hasSingleSignature ? Object.values(callback.signatures)[0] : callback
if (numberOfArguments >= 1 && numberOfArguments <= 3) {
return (...args) => tryFunctionWithArgs(fastCallback, args.slice(0, numberOfArguments), name, callback.name)
Expand All @@ -25,7 +25,17 @@ export function optimizeCallback (callback, array, name) {
return callback
}

export function findNumberOfArguments (callback, value, index, array) {
export function findNumberOfArguments (callback, array) {
if (typed.isTypedFunction(callback)) {
const firstIndex = (array.isMatrix ? array.size() : arraySize(array)).map(() => 0)
const firstValue = array.isMatrix ? array.get(firstIndex) : get(array, firstIndex)
return _typedFindNumberOfArguments(callback, firstValue, firstIndex, array)
} else {
return callback.length
}
}

function _typedFindNumberOfArguments (callback, value, index, array) {
const testArgs = [value, index, array]
for (let i = 3; i > 0; i--) {
const args = testArgs.slice(0, i)
Expand Down

0 comments on commit c7d98df

Please sign in to comment.