Ну, простой, но важный вопрос.Функциональному JS определенно не хватает универсального метода развертывания в объекте Array, поскольку нам может потребоваться создать массив числовых элементов не только простого [1,2,3,...,111]
, но и ряда, являющегося результатом функции, может быть как x => x*2
вместо x => x
В настоящее время для выполнения этой работы мы должны полагаться на метод Array.prototype.map()
.Однако для использования Array.prototype.map()
нам нужно заранее знать размер массива.Ну, все же .. если мы не знаем размер, то мы можем использовать Array.prototype.reduce()
, но Array.prototype.reduce()
предназначен для уменьшения (складывания), а не разворачивания вправо ..?
Так что, очевидно, нам нужен Array.unfold()
инструмент в функционале JS.Это то, что мы можем просто реализовать сами, например:
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.push(f(v)),runner(t(v)), res);
return runner(s);
};
Arrays.unfold(p,f,t,v)
принимает 4 аргумента.
- p Это функция, которая определяетгде остановитьсяФункция
p
принимает 3 аргумента, как это делают многие функторы массива.Значение, индекс и текущий результирующий массив.Он должен возвращать логическое значение.Когда он возвращает true
, рекурсивная итерация останавливается. - f Эта функция возвращает функциональное значение следующих элементов.
- t Эта функция возвращает следующий аргумент для подачи в f в следующем повороте.
- s Это начальное значение, которое будет использоваться для расчета удобного местас индексом 0 на
f
.
Так что, если мы намереваемся создать массив, заполненный серией, такой как 1,4,9,16,25 ... n ^ 2, мы можем просто сделать как.
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.push(f(v)),runner(t(v)), res);
return runner(s);
};
var myArr = Array.unfold((_,i) => i >= 9, x => Math.pow(x,2), x => x+1, 1);
console.log(myArr);