ES6(ECMAScript 6)에 변수 없이 x회 루프하는 메커니즘이 있습니까?
인 " " " " " "x
자바스크립트
for (var i = 0; i < x; i++)
doStuff(i);
저는 이 말을 않아요.++
또는 . ES6에서 ES6를 루프하는요?x
른른른른른른?루비의 메커니즘이 마음에 들어요.
x.times do |i|
do_stuff(i)
end
JavaScript/ES6에 유사한 것이 있습니까?커닝해서 발전기를 만들 수도 있어요
function* times(x) {
for (var i = 0; i < x; i++)
yield i;
}
for (var i of times(5)) {
console.log(i);
}
지금도 i++
적어도 눈에 띄지 않는 것이긴 하지만 ES6에 더 나은 메커니즘이 있었으면 합니다.
ES2015 스프레드 연산자 사용:
[...Array(n)].map()
const res = [...Array(10)].map((_, i) => {
return i * 10;
});
// as a one liner
const res = [...Array(10)].map((_, i) => i * 10);
또는 결과가 필요 없는 경우:
[...Array(10)].forEach((_, i) => {
console.log(i);
});
// as a one liner
[...Array(10)].forEach((_, i) => console.log(i));
또는 연산자의 ES2015 Array.from을 사용합니다.
Array.from(...)
const res = Array.from(Array(10)).map((_, i) => {
return i * 10;
});
// as a one liner
const res = Array.from(Array(10)).map((_, i) => i * 10);
문자열 반복만 필요한 경우 String.protype.repeat을 사용할 수 있습니다.
console.log("0".repeat(10))
// 0000000000
네!
아래 코드는 ES6 구문을 사용하여 작성되지만 ES5 또는 그 이하에서도 쉽게 작성될 수 있습니다.ES6는 'x회 루프 메커니즘'을 작성하기 위한 요건이 아닙니다.
콜백에 반복기가 필요 없는 경우, 이것이 가장 간단한 구현입니다.
const times = x => f => {
if (x > 0) {
f()
times (x - 1) (f)
}
}
// use it
times (3) (() => console.log('hi'))
// or define intermediate functions for reuse
let twice = times (2)
// twice the power !
twice (() => console.log('double vision'))
반복기가 필요한 경우 카운터 매개 변수와 함께 명명된 내부 함수를 사용하여 반복할 수 있습니다.
const times = n => f => {
let iter = i => {
if (i === n) return
f (i)
iter (i + 1)
}
return iter (0)
}
times (3) (i => console.log(i, 'hi'))
더 많은 것을 배우고 싶지 않다면 여기서 그만 읽으세요.
하지만 뭔가 기분이 안 좋을 거야
- 브런치 " " "
if
스테이트먼트는 못생겨요.다른 브랜치에서는 어떻게 됩니까? - 기능 본체의 여러 문장/설명서 - 절차상의 문제가 혼재하고 있습니까?
- 으로 반환된 「」
undefined
기능 : '불순물', '불순물', '불순물'
더 좋은 방법은 없을까?
있어.우선, 초기 실장을 재검토해 봅시다.
// times :: Int -> (void -> void) -> void
const times = x => f => {
if (x > 0) {
f() // has to be side-effecting function
times (x - 1) (f)
}
}
'우리', '우리', '우리', '우리'라고 부르면 돼요.f()
여러번 할 수 가 크게 됩니다.이로 인해 여러 번 반복할 수 있는 기능의 유형이 제한됩니다.수 있다고 , 「반복기」는 사용할 수 있습니다.f(i)
하다
더 나은 종류의 기능 반복 절차로 시작하면 어떨까요?입력과 출력을 더 잘 활용할 수 있는 방법일 수도 있습니다.
일반 함수 반복
// repeat :: forall a. Int -> (a -> a) -> a -> a
const repeat = n => f => x => {
if (n > 0)
return repeat (n - 1) (f) (f (x))
else
return x
}
// power :: Int -> Int -> Int
const power = base => exp => {
// repeat <exp> times, <base> * <x>, starting with 1
return repeat (exp) (x => base * x) (1)
}
console.log(power (2) (8))
// => 256
인 generic a a,, 리는 a a a a a a a a a a a a a a a a를 했습니다.repeat
단일 기능의 반복 적용을 시작하는 데 사용되는 추가 입력을 받는 함수입니다.
// repeat 3 times, the function f, starting with x ...
var result = repeat (3) (f) (x)
// is the same as ...
var result = f(f(f(x)))
★★의 times
repeat
지금은 간단합니다.대부분의 작업은 이미 완료되어 있습니다.
// repeat :: forall a. Int -> (a -> a) -> a -> a
const repeat = n => f => x => {
if (n > 0)
return repeat (n - 1) (f) (f (x))
else
return x
}
// times :: Int -> (Int -> Int) -> Int
const times = n=> f=>
repeat (n) (i => (f(i), i + 1)) (0)
// use it
times (3) (i => console.log(i, 'hi'))
는 리리기기 since since를 사용하기 i
으로서 「」를 반환한다.i + 1
가 ''로 '로f
★★★★★★ 。
문제의 총탄 목록도 수정했습니다.
- 이상 단일 브랜치는 없습니다.
if
(START) - 단일 표현체는 잘 분리된 우려를 나타낸다.
- 쓸모없고 되지 않습니다.
undefined
JavaScript 콤마 연산자,
마지막 예제가 어떻게 동작하고 있는지 알 수 없는 경우 JavaScript의 가장 오래된 전투 축 중 하나인 쉼표 연산자의 인식에 따라 달라집니다.즉, 왼쪽에서 오른쪽으로 식을 평가하여 마지막으로 평가한 식의 값을 반환합니다.
(expr1 :: a, expr2 :: b, expr3 :: c) :: c
위의 예에서 저는
(i => (f(i), i + 1))
간결한 글쓰기 방법일 뿐이죠
(i => { f(i); return i + 1 })
테일콜 최적화
재귀적인 구현이 매력적이기는 하지만 적절한 테일콜 제거를 지원하는 JavaScript VM이 없다고 생각되는 현시점에서는 권장하는 것은 무책임합니다.바벨은 변환에 사용되었지만 1년 이상 "broken; will reimplement" 상태입니다.
repeat (1e6) (someFunc) (x)
// => RangeError: Maximum call stack size exceeded
그 때문에, 델의 실장을 재검토할 필요가 있습니다.repeat
안전하게 쌓기 위해서요
아래 코드는 가변 변수를 사용합니다.n
★★★★★★★★★★★★★★★★★」x
, 모든 는 '변형'에 .repeat
function - 볼수. - 상태 변화(변화)는 기능 외부에서 볼 수 없습니다.
// repeat :: Int -> (a -> a) -> (a -> a)
const repeat = n => f => x =>
{
let m = 0, acc = x
while (m < n)
(m = m + 1, acc = f (acc))
return acc
}
// inc :: Int -> Int
const inc = x =>
x + 1
console.log (repeat (1e8) (inc) (0))
// 100000000
이 "하지 않아라고 말할 요. 진정하세요.그런데 기능하지 않아!"라고 말하는 사람이 많을 것입니다.-알겠습니다. 긴장 푸세요.이 가능합니다.loop
/recur
순수 표현을 사용한 고정 공간 루프용 인터페이스.while
strupdiscloss.discloss.
요약해 .while
우리의 것을 버리고loop
– – 한 기능 – 을 찾습니다.recur
활자recur
됩니다.
const recur = (...args) =>
({ type: recur, args })
const loop = f =>
{
let acc = f ()
while (acc.type === recur)
acc = f (...acc.args)
return acc
}
const repeat = $n => f => x =>
loop ((n = $n, acc = x) =>
n === 0
? acc
: recur (n - 1, f (acc)))
const inc = x =>
x + 1
const fibonacci = $n =>
loop ((n = $n, a = 0, b = 1) =>
n === 0
? a
: recur (n - 1, b, a + b))
console.log (repeat (1e7) (inc) (0)) // 10000000
console.log (fibonacci (100)) // 354224848179262000000
for (let i of Array(100).keys()) {
console.log(i)
}
또 다른 좋은 대안이 있습니다.
Array.from({ length: 3}).map(...);
@처럼 @Dave Morse는 @Dave Morse, @Dave Morse를 .map
"의 두 번째 를 사용하여 콜을 실행합니다.Array.from
뭇매를 맞다
Array.from({ length: 3 }, () => (...))
가장 좋은 해결방법은 이 시스템에let
:
for (let i=0; i<100; i++) …
가능한) (변환 가능한) ( 가능한) 것이 됩니다.i
이며, 이 변수가 합니다.i
는 그 루프 구문의 증분식으로만 변경되며 다른 곳에서는 변경되지 않습니다.
적어도 어어 least least
i++
보이지 않는다:)
그만하면 충분할 거야, 임오.순수 언어에서도 모든 작업(또는 적어도 해당 인터프리터)은 변환을 사용하는 원시 요소에서 구축됩니다.스코프가 제대로 되어 있으면 뭐가 문제인지 알 수 없어요.
그럼 괜찮겠지?
function* times(n) {
for (let i = 0; i < n; i++)
yield i;
}
for (const i of times(5)) {
console.log(i);
}
저는 이 말을 않아요.
++
또는 .
을 사용하다 가능한 것이 아니라 할 수 .i
아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.
function* range(i, n) {
if (i >= n) return;
yield i;
return yield* range(i+1, n);
}
times = (n) => range(0, n);
, 문제가 있을 이 있습니다(「」은 「Tail Call Removation」을 수 없기 때문에, 「Tail Call Removation」을 사용할 수 없습니다).return yield*
를 참조해 주세요.
나는 이것이 꽤 간단하다고 생각한다.
[...Array(3).keys()]
또는
Array(3).fill()
const times = 4;
new Array(times).fill().map(() => console.log('test'));
은 ★★★★★★★★★★★★★★★★」console.log
test
4인치.
답변: 2015년 12월 9일
개인적으로, 나는 받아들여진 답이 간결하고 간결하다는 것을 알았다.이 문장은 주관적일 수 있으므로 이 답변을 읽고 동의 여부를 확인하십시오.
질문의 예는 Ruby와 같은 것입니다.
x.times do |i|
do_stuff(i)
end
이것을 JS로 나타내면, 이하를 사용할 수 있습니다.
times(x)(doStuff(i));
코드는 다음과 같습니다.
let times = (n) => {
return (f) => {
Array(n).fill().map((_, i) => f(i));
};
};
바로 그거야!
간단한 사용 예:
let cheer = () => console.log('Hip hip hooray!');
times(3)(cheer);
//Hip hip hooray!
//Hip hip hooray!
//Hip hip hooray!
또는 승인된 답변의 예를 다음에 나타냅니다.
let doStuff = (i) => console.log(i, ' hi'),
once = times(1),
twice = times(2),
thrice = times(3);
once(doStuff);
//0 ' hi'
twice(doStuff);
//0 ' hi'
//1 ' hi'
thrice(doStuff);
//0 ' hi'
//1 ' hi'
//2 ' hi'
측면 참고 - 범위 함수 정의
기본적으로 매우 유사한 코드 구조를 사용하는 유사한/관련 질문은 (코어) JavaScript에 언더스코어의 범위 함수와 유사한 편리한 범위 함수가 있는지 여부일 수 있습니다.
x부터 n개의 숫자로 어레이를 만듭니다.
밑줄
_.range(x, x + n)
ES2015
몇 가지 대안:
Array(n).fill().map((_, i) => x + i)
Array.from(Array(n), (_, i) => x + i)
n = 10, x = 1을 사용한 데모:
> Array(10).fill().map((_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
> Array.from(Array(10), (_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
간단한 테스트에서 솔루션과 doStuff 함수를 사용하여 각각 100만 번 실행한 결과 이전 접근법(Array(n.fill))이 약간 더 빠르다는 것이 입증되었습니다.
파티에 늦었습니다만, 이 질문은 검색 결과에 자주 표시되기 때문에, 길지 않고 가독성 면에서 가장 좋다고 생각되는 솔루션을 추가하고 싶습니다(이것은 모든 코드 베이스 IMO에 이상적입니다).변이되긴 하지만 KISS 원칙과 맞바꾸겠어요
let times = 5
while( times-- )
console.log(times)
// logs 4, 3, 2, 1, 0
Array(100).fill().map((_,i)=> console.log(i) );
이 버전은 불변성에 대한 OP의 요구사항을 충족합니다., ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴreduce
map
사용 사례에 따라 다릅니다.
시제품에 약간의 돌연변이가 있어도 괜찮다면 이 옵션도 선택할 수 있습니다.
Number.prototype.times = function(f) {
return Array(this.valueOf()).fill().map((_,i)=>f(i));
};
이제 우린 할 수 있어
((3).times(i=>console.log(i)));
- 아크셀돈에 에 대한 +1 - 아크셀돈에 대한 아크셀돈.fill
★★★★★★ 。
가르쳐 주거나 코드에 사용하는 것은 아니지만, 변수를 변환하지 않고 ES6를 필요로 하지 않는 코드 골프에 적합한 솔루션을 소개합니다.
Array.apply(null, {length: 10}).forEach(function(_, i){
doStuff(i);
})
유용한 대답이라기보다 흥미로운 개념 증명 같은 거요
라이브러리를 사용할 의향이 있는 경우 lodash 또는 언더스코어:
_.times(x, i => {
return doStuff(i)
})
결과 배열이 반환되므로 실제로는 다음과 같은 루비에 가깝습니다.
x.times.map { |i|
doStuff(i)
}
의 ES6와 times
재귀를 수 있습니다.그러나 재귀를 사용하면 변환을 방지할 수 있습니다.
let times = (i, cb, l = i) => {
if (i === 0) return;
cb(l - i);
times(i - 1, cb, l);
}
times(5, i => doStuff(i));
데모: http://jsbin.com/koyecovano/1/edit?js,console
repeat
는 보통 무한 재귀 함수입니다.그것을 이용하려면 우리는 게으른 평가나 계속 패스하는 스타일이 필요하다.
느린 평가 함수 반복
const repeat = f => x => [x, () => repeat(f) (f(x))];
const take = n => ([x, f]) => n === 0 ? x : take(n - 1) (f());
console.log(
take(8) (repeat(x => x * 2) (1)) // 256
);
Javascript에서 느린 평가를 얻기 위해 Thunk(인수가 없는 함수)를 사용합니다.
연속 패싱 스타일로 기능 반복
const repeat = f => x => [x, k => k(repeat(f) (f(x)))];
const take = n => ([x, k]) => n === 0 ? x : k(take(n - 1));
console.log(
take(8) (repeat(x => x * 2) (1)) // 256
);
CPS를 사용합니다.: ,,, 항항같같 however however however however however however however however however however however however however however however however however however however 。는 '으로, 본문을 호출합니다.k => k(...)
CPS는 어플리케이션을 .take(8) (repeat...)
becomes가 되다k(take(8)) (...)
서 ''는k
으로 적용된 "" 입니다.repeat
.
결론
으로써 (반복)repeat
조건 「 」 )으로부터을 참조해 주세요.take
) 유연성이 확보됩니다.'CHANGE: 'CHANGE: 'CHANGE: 'C" :D.
이 솔루션의 장점
- 읽기/사용이 가장 간단함(imo)
- 반환 값은 합계로 사용하거나 그냥 무시할 수 있습니다.
- 플레인 es6 버전, TypeScript 버전 코드에 링크합니다.
단점 - 돌연변이.나만 내면적이기 때문에 다른 사람들도 신경 쓰지 않을 것이다.
예와 코드
times(5, 3) // 15 (3+3+3+3+3)
times(5, (i) => Math.pow(2,i) ) // 31 (1+2+4+8+16)
times(5, '<br/>') // <br/><br/><br/><br/><br/>
times(3, (i, count) => { // name[0], name[1], name[2]
let n = 'name[' + i + ']'
if (i < count-1)
n += ', '
return n
})
function times(count, callbackOrScalar) {
let type = typeof callbackOrScalar
let sum
if (type === 'number') sum = 0
else if (type === 'string') sum = ''
for (let j = 0; j < count; j++) {
if (type === 'function') {
const callback = callbackOrScalar
const result = callback(j, count)
if (typeof result === 'number' || typeof result === 'string')
sum = sum === undefined ? result : sum + result
}
else if (type === 'number' || type === 'string') {
const scalar = callbackOrScalar
sum = sum === undefined ? scalar : sum + scalar
}
}
return sum
}
versionTypeScipt " "
https://codepen.io/whitneyland/pen/aVjaaE?editors=0011httpscodepen.io//pen/aVjaaE?editors=0011
범위 내 목록/배열을 만드는 가장 간단한 방법
Array.from(Array(max-min+1), (_, index) => index+min)
기능적인 측면에 대한 대응:
function times(n, f) {
var _f = function (f) {
var i;
for (i = 0; i < n; i++) {
f(i);
}
};
return typeof f === 'function' && _f(f) || _f;
}
times(6)(function (v) {
console.log('in parts: ' + v);
});
times(6, function (v) {
console.log('complete: ' + v);
});
발전기?재귀?왜 그렇게 변태에 대해 모호한거야?;-)
"숨기기"만 하면 되는 경우 단항 연산자의 사용을 수락하면 다음과 같이 단순하게 유지할 수 있습니다.
Number.prototype.times = function(f) { let n=0 ; while(this.valueOf() > n) f(n++) }
루비처럼:
> (3).times(console.log)
0
1
2
도우미 기능으로 @Tieme의 답변을 마무리했습니다.
TypeScript의 경우:
export const mapN = <T = any[]>(count: number, fn: (...args: any[]) => T): T[] => [...Array(count)].map((_, i) => fn())
이제 실행할 수 있습니다.
const arr: string[] = mapN(3, () => 'something')
// returns ['something', 'something', 'something']
내가 만든 거야:
function repeat(func, times) {
for (var i=0; i<times; i++) {
func(i);
}
}
사용방법:
repeat(function(i) {
console.log("Hello, World! - "+i);
}, 5)
/*
Returns:
Hello, World! - 0
Hello, World! - 1
Hello, World! - 2
Hello, World! - 3
Hello, World! - 4
*/
그i
variable은 루프된 횟수를 반환합니다.x 개의 이미지를 프리로드 할 필요가 있는 경우에 편리합니다.
이거 그냥 여기에 놓을게요.어레이를 사용하지 않고 콤팩트한 기능을 찾고 있으며, 가변성/불변성에 문제가 없는 경우:
var g =x=>{/*your code goes here*/x-1>0?g(x-1):null};
이것은, 많은 레벨의 개발자에게 있어서 가장 알기 쉬운 대답입니다.
const times = (n, callback) => {
while (n) {
callback();
n--;
}
}
times(10, ()=> console.log('hello'))
이 질문에 대한 가장 정확한 답변은 사샤 콘드라쇼프의 코멘트에 담겨 있고, 또한 가장 간결한 두 글자로 "아니오"라는 두 글자를 사용하고 있는 것 같습니다.루비가 가진 구문만큼 좋은 for-loop의 기능적인 대안은 없습니다.우리는 그것이 있기를 바랄지도 모르지만, 그것은 아니다.
질문에는 명확하게 기술되어 있지 않지만, 나는 'N번 루프' 문제에 대한 어떤 해결책도 적어도 N번과 비례하지 않는 메모리를 할당해서는 안 된다고 주장한다.이 기준에서는 'javascript에 네이티브'인 대부분의 답변은 제외됩니다.
다른 답변은 Ruby와 같은 구현을 보여주는데, 이 질문은 네이티브 Javascript 솔루션을 명시적으로 요구하는 것을 제외하고는 괜찮습니다.이 질문에는 이미 매우 훌륭한 해법이 있습니다. 거의 틀림없이 가장 읽기 쉬운 것 중 하나입니다.
언급URL : https://stackoverflow.com/questions/30452263/is-there-a-mechanism-to-loop-x-times-in-es6-ecmascript-6-without-mutable-varia
'programing' 카테고리의 다른 글
유클리드 거리는 NumPy로 어떻게 계산될 수 있나요? (0) | 2022.11.05 |
---|---|
Angular 2 옵션루트 파라미터 (0) | 2022.11.05 |
Mixin 렌더 함수 구성 (0) | 2022.10.27 |
웹 페이지가 iframe 내에 로드되어 있는지 브라우저 창에 직접 로드되어 있는지 확인하는 방법 (0) | 2022.10.27 |
github에서 pip 설치가 작동하도록 구성 (0) | 2022.10.27 |