Цель
Я пытаюсь создать функцию "deepMapValues". Он возьмет такую функцию, как ...
(v, k) => k == 'hello' ? 'world' : v;
// if the key is 'hello' then return the value 'world' else return the value that already exists there.
И объект, подобный ...
{
hello: true,
foo: {
hello: 'bar'
}
}
И вернет объект ..
{
hello: 'world',
foo: {
hello: 'world'
}
}
Использование это так ... deepMap(mapFunction)(inputObject)
Моя текущая функция
Я написал эту маленькую функцию, используя loda sh ...
const mapValuesWithKey = _.mapValues.convert({ 'cap': false });
// this is because I want both the value and key passed into the map function
deepMap = fn => mapValuesWithKey(
_.cond([
[_.isArray, _.map(deepMap(fn))],
[_.isPlainObject, deepMap(fn)],
[_.T, fn],
])
);
Когда я ее запускаю Я немедленно получаю cra sh ...
RangeError: Превышен максимальный размер стека вызовов
Что можно ожидать, так как функция рекурсивна и, если не выполнена, правильно он будет бесконечно повторяться.
Однако я изменил его на это (только для тестирования) ...
deepMap = fn => mapValuesWithKey(
_.cond([
[_.T, fn],
])
);
И это сработало (что снова ожидается).
Но когда я изменил его на это ...
deepMap = fn => mapValuesWithKey(
_.cond([
[_.T, fn],
[_.F, deepMap(fn)],
])
);
Он снова упал с той же ошибкой. Несмотря на то, что рекурсия НИКОГДА не произойдет в приведенном выше коде, она все еще превышает размер стека вызовов.
Используя код loda sh из Github, я подозревал, что перед выполнением команды он может оценить все пары в _.cond
код, поэтому я написал свою собственную версию cond
.
const myCond = pairs => {
return (...args) => {
for (const pair of pairs) {
if (pair[0](args)) {
return pair[1](args)
}
}
}
};
Но это также все еще сбой.
Я не уверен, что я делаю здесь неправильно, как кажется быть рекурсивным, даже если для него не может быть рекурсии?
Что я делаю не так?
Спасибо
Rubber Duck EDIT
Я думаю, что это может быть потому, что функция оценивается с помощью параметра fn
, а затем создает объект в паре cond
, которая повторяется с fn
, который делает то же самое снова и снова и снова ...
Расследование.
Дополнительный вопрос
Если приведенное выше верно ... как я могу остановить ошибку, но все же передать fn
через рекурсия?