Рассмотрим следующую реализацию take
:
const take = (n, [x, ...xs]) =>
n === 0 || x === undefined ?
[] : [x, ...take(n - 1, xs)];
console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
console.log(take(1, [undefined, 1])); // []
Как вы можете видеть, он не работает для массивов с undefined
потому что x === undefined
не лучший способ проверить, пуст ли массив. Следующий код исправляет эту проблему:
const take = (n, xs) =>
n === 0 || xs.length === 0 ?
[] : [xs[0], ...take(n - 1, xs.slice(1))];
console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
console.log(take(1, [undefined, 1])); // [undefined]
Однако запись xs[0]
и xs.slice(1)
не такая элегантная. Кроме того, это проблематично, если вам нужно использовать их несколько раз. Либо вам придется дублировать код и выполнять лишнюю дополнительную работу, либо вам придется создавать область блока, определять константы и использовать ключевое слово return.
Лучшим решением было бы использовать выражение let. К сожалению, JavaScript их не имеет. Итак, как имитировать let выражения в JavaScript?
В Lisp выражение let является просто синтаксическим сахаром для левой левой лямбда (т.е. Непосредственно вызываемого функционального выражения). Например, рассмотрим:
(let ([x 1]
[y 2])
(+ x y))
; This is syntactic sugar for:
((lambda (x y)
(+ x y))
1 2)
В ES6 мы можем использовать функции стрелок и параметры по умолчанию для создания IIFE, который выглядит как выражение let следующим образом:
const z = ((x = 1, y = 2) => x + y)();
console.log(z);
С помощью этого хака, мы можем определить take
следующим образом:
const take = (n, xxs) =>
n === 0 || xxs.length === 0 ?
[] : (([x, ...xs] = xxs) => [x, ...take(n - 1, xs)])();
console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
console.log(take(1, [undefined, 1])); // [undefined]
Надеюсь, это поможет.
undefined
- это реальное значение, но не часть разреженного массива с его использованием. реальный разреженный массив выглядит как[, 1]
.[, 1]
и[undefined, 1]
были эквивалентны, но, видимо, это не так. Спасибо, что дал мне знать.