Существует однострочный подход, включающий использование вложенной функции закрытия в
конструктор списка. И функция, которая работает долго, чтобы генерировать последовательность.
Это определено ниже:
var __ = generate = function(initial, max, list, comparision) {
if (comparision(initial))
list.push(initial);
return (initial += 1) == max + 1 ? list : __(initial, max, list, comparision);
};
[(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))];
// returns Array[20]
var val = 16;
[(function(l){ return l; })(__(0, 30, [], function(x) { return x % val == 4; }))];
// returns Array[2]
Это реализация, основанная на диапазоне, например диапазон Python (min, max)
Кроме того, понимание списка следует этой форме:
[{closure function}({generator function})];
некоторые тесты:
var alist = [(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))];
var alist2 = [(function(l){ return l; })(__(0, 1000, [], function(x) { return x > 10; }))];
// returns Array[990]
var alist3 = [(function(l){ return l; })(__(40, 1000, [], function(x) { return x > 10; }))];
var threshold = 30*2;
var alist3 = [(function(l){ return l; })(__(0, 65, [], function(x) { return x > threshold; }))];
// returns Array[5]
Хотя это решение не самое чистое, оно выполняет свою работу. И в производстве я бы, вероятно, советовал против этого.
Наконец, можно выбрать не использовать рекурсию для моего метода «генерирования», так как это сделает работу быстрее. Или даже лучше использовать встроенную функцию из многих популярных библиотек Javascript. Вот перегруженная реализация, которая также приспособилась бы для свойств объекта
// A list generator overload implementation for
// objects and ranges based on the arity of the function.
// For example [(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))]
// will use the first implementation, while
// [(function(l){ return l; })(__(objects, 'name', [], function(x, y) { var x = x || {}; return x[y] }))];
// will use the second.
var __ = generator = function(options) {
return arguments.length == 4 ?
// A range based implemention, modeled after pythons range(0, 100)
(function (initial, max, list, comparision) {
var initial = arguments[0], max = arguments[1], list = arguments[2], comparision = arguments[3];
if (comparision(initial))
list.push(initial);
return (initial += 1) == max + 1 ? list : __(initial, max, list, comparision);
})(arguments[0], arguments[1], arguments[2], arguments[3]):
// An object based based implementation.
(function (object, key, list, check, acc) {
var object = arguments[0], key = arguments[1], list = arguments[2], check = arguments[3], acc = arguments[4];
acc = acc || 0;
if (check(object[acc], key))
list.push(object[acc][key]);
return (acc += 1) == list.length + 1 ? list : __(object, key, list, check, acc);
})(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
};
Использование:
var threshold = 10;
[(function(l){ return l; })(__(0, 65, [], function(x) { return x > threshold; }))];
// returns Array[5] -> 60, 61, 62, 63, 64, 65
var objects = [{'name': 'joe'}, {'name': 'jack'}];
[(function(l){ return l; })(__(objects, 'name', [], function(x, y) { var x = x || {}; return x[y] }))];
// returns Array[1] -> ['Joe', 'Jack']
[(function(l){ return l; })(__(0, 300, [], function(x) { return x > 10; }))];
Синтаксис отстой, я знаю!
Удачи.