ES2015에서만 0에서 9까지의 범위의 숫자를 생성하는 방법은 무엇입니까?
나는 항상 그것을 찾았습니다.range
파이썬 등에서 사용할 수 있는 자바스크립트에서 함수가 누락되었습니까?ES2015에서 숫자 범위를 생성할 수 있는 간결한 방법이 있습니까?
편집: 내 질문은 ECMASCRIPT-5가 아닌 ES2015에만 해당되므로 언급된 중복 질문과 다릅니다.또한 특정 시작 번호가 아닌 0부터 시작하는 범위가 필요합니다(그것이 있다면 좋을 것입니다).
새로 만든 배열의 키에서 스프레드 연산자를 사용할 수 있습니다.
[...Array(n).keys()]
또는
Array.from(Array(n).keys())
그Array.from()
TypeScript로 작업할 경우 구문이 필요합니다.
나는 또한 사용하는 더 직관적인 방법을 찾았습니다.Array.from
:
const range = n => Array.from({length: n}, (value, key) => key)
자, 이거range
함수는 0부터 n-1까지의 모든 숫자를 반환합니다.
지원할 범위의 수정된 버전start
그리고.end
다음과 같습니다.
const range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
EDIT @marco6에서 제안한 것처럼, 당신의 사용 사례에 적합하다면 이것을 정적 방법으로 넣을 수 있습니다.
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
그리고 그것을 사용합니다.
Array.range(3, 9)
델타/스텝 포함
가장 작은 원라이너
[...Array(N)].map((_, i) => from + i * step);
예제 및 기타 대안
[...Array(10)].map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10)).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Array(10).fill(0).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array(10).fill().map((_, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
범위 함수
const range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
range(0, 9, 2);
//=> [0, 2, 4, 6, 8]
// can also assign range function as static method in Array class (but not recommended )
Array.range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]
Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.range(2, 10, -1);
//=> []
Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
반복자로서
class Range {
constructor(total = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
for (let i = 0; i < total; yield from + i++ * step) {}
};
}
}
[...new Range(5)]; // Five Elements
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Five Elements With Step 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
생성자 전용
const Range = function* (total = 0, step = 1, from = 0) {
for (let i = 0; i < total; yield from + i++ * step) {}
};
Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]
[...Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
// Lazy loaded way
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
시작/종료(단계/델타 포함)
반복기 사용
class Range2 {
constructor(to = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
}
}
[...new Range2(5)]; // First 5 Whole Numbers
//=> [0, 1, 2, 3, 4, 5]
[...new Range2(5, 2)]; // From 0 to 5 with step 2
//=> [0, 2, 4]
[...new Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
생성기 사용
const Range2 = function* (to = 0, step = 1, from = 0) {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
[...Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
숫자 0부터 5까지
[...Array(5).keys()];
=> [0, 1, 2, 3, 4]
이러한 솔루션의 대부분은 실제 어레이 개체를 인스턴스화하는 것을 기반으로 합니다. 이는 많은 경우에 작업을 수행할 수 있지만 다음과 같은 경우에는 지원할 수 없습니다.range(Infinity)
간단한 생성기를 사용하여 이러한 문제를 방지하고 무한 시퀀스를 지원할 수 있습니다.
function* range( start, end, step = 1 ){
if( end === undefined ) [end, start] = [start, 0];
for( let n = start; n < end; n += step ) yield n;
}
예:
Array.from(range(10)); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Array.from(range(10, 20)); // [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
i = range(10, Infinity);
i.next(); // { value: 10, done: false }
i.next(); // { value: 11, done: false }
i.next(); // { value: 12, done: false }
i.next(); // { value: 13, done: false }
i.next(); // { value: 14, done: false }
따라서 이 경우 Number 개체가 확산 연산자를 사용하는 Array 개체처럼 동작하면 좋습니다.
예를 들어, 스프레드 연산자와 함께 사용되는 Array 개체:
let foo = [0,1,2,3];
console.log(...foo) // returns 0 1 2 3
Array 개체에 내장된 반복기가 있기 때문에 이렇게 작동합니다.
이 경우 비슷한 기능을 사용하려면 Number 개체가 필요합니다.
[...3] //should return [0,1,2,3]
그러기 위해서는 단순히 그 목적을 위한 숫자 반복기를 만들 수 있습니다.
Number.prototype[Symbol.iterator] = function *() {
for(let i = 0; i <= this; i++)
yield i;
}
이제 산포 연산자를 사용하여 0부터 N까지의 범위를 만들 수 있습니다.
[...N] // 이제 0을 반환합니다...N 배열
http://jsfiddle.net/01e4xdv5/4/
건배.
python과 유사하게 작동하는 ES6 단계의 범위list(range(start, stop[, step]))
:
const range = (start, stop, step = 1) => {
return [...Array(stop - start).keys()]
.filter(i => !(i % Math.round(step)))
.map(v => start + v)
}
예:
range(0, 8) // [0, 1, 2, 3, 4, 5, 6, 7]
range(4, 9) // [4, 5, 6, 7, 8]
range(4, 9, 2) // [4, 6, 8]
range(4, 9, 3) // [4, 7]
필요한 경우에만 범위를 느리게 만드는 제너레이터 기능을 사용할 수 있습니다.
function* range(x, y) {
while (true) {
if (x <= y)
yield x++;
else
return null;
}
}
const infiniteRange = x =>
range(x, Infinity);
console.log(
Array.from(range(1, 10)) // [1,2,3,4,5,6,7,8,9,10]
);
console.log(
infiniteRange(1000000).next()
);
고차 제너레이터 기능을 사용하여 다음을 매핑할 수 있습니다.range
생성기:
function* range(x, y) {
while (true) {
if (x <= y)
yield x++;
else
return null;
}
}
const genMap = f => gx => function* (...args) {
for (const x of gx(...args))
yield f(x);
};
const dbl = n => n * 2;
console.log(
Array.from(
genMap(dbl) (range) (1, 10)) // [2,4,6,8,10,12,14,16,18,20]
);
두려움이 없다면 제너레이터 접근 방식을 일반화하여 훨씬 더 광범위한 범위(펀 의도)를 해결할 수도 있습니다.
const rangeBy = (p, f) => function* rangeBy(x) {
while (true) {
if (p(x)) {
yield x;
x = f(x);
}
else
return null;
}
};
const lte = y => x => x <= y;
const inc = n => n + 1;
const dbl = n => n * 2;
console.log(
Array.from(rangeBy(lte(10), inc) (1)) // [1,2,3,4,5,6,7,8,9,10]
);
console.log(
Array.from(rangeBy(lte(256), dbl) (2)) // [2,4,8,16,32,64,128,256]
);
으로 상태를 즉, ""/" "" "" "" "" "" "" "" "" "" ""의 호출에 따라 하십시오.next
국가는 복합적인 축복입니다.
델타 지원
const range = (start, end, delta) => {
return Array.from(
{length: (end - start) / delta}, (v, k) => (k * delta) + start
)
};
매핑하는 게 어때요?
Array(n).map((값, 인덱스)...)은 전체 경로의 80%입니다.하지만 어떤 이상한 이유로 그것은 작동하지 않습니다.하지만 해결책이 있습니다.
Array(n).map((v,i) => i) // does not work
Array(n).fill().map((v,i) => i) // does dork
범위에 대해
Array(end-start+1).fill().map((v,i) => i + start) // gives you a range
홀수,이두결과를 합니다: 홀수, 이두반는동일결한반다환니.Array(end-start+1).entries()
그리고.Array(end-start+1).fill().entries()
다음과 같은 단계 지원이 있는 하나의 라이너로도 이 작업을 수행할 수 있습니다.
((from, to, step) => ((add, arr, v) => add(arr, v, add))((arr, v, add) => v < to ? add(arr.concat([v]), v + step, add) : arr, [], from))(0, 10, 1)
는 결는입니다.[0, 1, 2, 3, 4, 5, 6 ,7 ,8 ,9]
.
이 함수는 정수 시퀀스를 반환합니다.
const integerRange = (start, end, n = start, arr = []) =>
(n === end) ? [...arr, n]
: integerRange(start, end, start < end ? n + 1 : n - 1, [...arr, n]);
$> integerRange(1, 1)
<- Array [ 1 ]
$> integerRange(1, 3)
<- Array(3) [ 1, 2, 3 ]
$> integerRange(3, -3)
<- Array(7) [ 3, 2, 1, 0, -1, -2, -3 ]
몇 가지 더 할 수 있는 방법
// Using `repeat` and `map`
const gen = n => [...'.'.repeat(n)].map((_,i) => i);
console.log('gen ', gen(5));
// Using `repeat` and `split`
const gen2 = n => ' '.repeat(n).split('').map((_,i) => i);
console.log('gen2 ', gen2(5));
// Using `concat` with recursive approach
const gen3 = n => n ? gen3(n-1).concat(n-1) : [];
console.log('gen3 ', gen3(5));
const range = (start, end, step = 1) =>
start > end ? [] : [start].concat(range(start + step, end, step));
console.log('range', range(2, 10,2));
const keys = Array(n).keys();
[...Array.from(keys)].forEach(callback);
타이프스크립트에서
다음은 사용하지 않는 또 다른 변형입니다.Array
.
let range = (n, l=[], delta=1) => {
if (n < 0) {
return l
}
else {
l.unshift(n)
return range(n - delta, l)
}
}
이제 제너레이터를 사용하면 숫자 시퀀스를 느리게 생성하고 넓은 범위에서 메모리를 적게 사용할 수 있습니다.
질문에 ES2015가 명시되어 있지만, 많은 유형 스크립트 사용자가 여기에 올 것으로 예상되며 ES로의 전환은 간단합니다.
function range(end: number): IterableIterator<number>;
// tslint:disable-next-line:unified-signatures
function range(begin: number, end: number): IterableIterator<number>;
function *range(begin: number, end: number = NaN): IterableIterator<number> {
let num = 0;
if (isNaN(end)) {
end = begin;
} else {
num = begin;
}
while (num < end) {
yield num++;
}
}
처음 두 개의 함수 선언은 IDE에서 보다 유용한 완료 제안을 제공하기 위한 것입니다.
언급URL : https://stackoverflow.com/questions/36947847/how-to-generate-range-of-numbers-from-0-to-n-in-es2015-only
'source' 카테고리의 다른 글
빌드: '노드'에 대한 형식 정의 파일을 찾을 수 없습니다. (0) | 2023.08.05 |
---|---|
CSS ":hover"를 활성화하는 순수 자바스크립트에서 마우스 오버를 시뮬레이션하려면 어떻게 해야 합니까? (0) | 2023.08.05 |
IsNullOr 또는 Empty와 IsNullOr의 차이C#의 WhiteSpace (0) | 2023.08.05 |
Gulp.js 작업, src로 돌아옵니까? (0) | 2023.08.05 |
루프 증가/감소에 대한 a가 하나 이상 증가할 수 있습니까? (0) | 2023.08.05 |