alias:: Transducer: 강력한 함수 구성 패턴
노트북:: 변환기: 一种强大的函数组同模式
맵 및 필터
맵의 의미는 '매핑'입니다. 이는 세트의 모든 요소에 대해 한 번 변환을 수행한다는 의미입니다.
const list = [1, 2, 3, 4, 5] list.map(x => x + 1) // [ 2, 3, 4, 5, 6 ]
function map(f, xs) { const ret = [] for (let i = 0; i <pre class="brush:php;toolbar:false"> map(x => x + 1, [1, 2, 3, 4, 5]) // [ 2, 3, 4, 5, 6 ]
위에서는 맵의 구현이 컬렉션 유형에 의존한다는 것을 명확하게 표현하기 위해 의도적으로 for 문을 사용했습니다.
순차적 실행;
게으르지 않고 즉각적인 평가.
필터를 살펴보겠습니다.
function filter(f, xs) { const ret = [] for (let i = 0; i <pre class="brush:php;toolbar:false"> var range = n => [...Array(n).keys()]
filter(x => x % 2 === 1, range(10)) // [ 1, 3, 5, 7, 9 ]
마찬가지로 필터 구현도 특정 컬렉션 유형에 따라 달라지며 현재 구현에서는 xs가 배열이어야 합니다.
지도는 어떻게 다양한 데이터 유형을 지원할 수 있나요? 예를 들어 집합, 지도 및 맞춤 데이터 유형이 있습니다.
일반적인 방법이 있습니다. 컬렉션의 인터페이스(프로토콜)에 의존합니다.
언어마다 구현 방식이 다르며 JS는 이와 관련하여 기본 지원이 상대적으로 약하지만 실현 가능합니다.
Symbol.iterator를 사용하여 반복합니다.
생성자를 얻으려면 Object#contractor를 사용하세요.
그렇다면 푸시에서 다양한 데이터 유형을 추상적으로 지원하려면 어떻게 해야 할까요?
ramdajs 라이브러리를 모방하여 맞춤 @@transducer/step 함수를 사용할 수 있습니다.
function map(f, xs) { const ret = new xs.constructor() // 1. construction for (const x of xs) { // 2. iteration ret['@@transducer/step'](f(x)) // 3. collection } return ret }
Array.prototype['@@transducer/step'] = Array.prototype.push // [Function: push]
map(x => x + 1, [1, 2, 3, 4, 5]) // [ 2, 3, 4, 5, 6 ]
Set.prototype['@@transducer/step'] = Set.prototype.add // [Function: add]
map(x => x + 1, new Set([1, 2, 3, 4, 5])) // Set (5) {2, 3, 4, 5, 6}
이 방법을 사용하면 지도, 필터 등 보다 축적인 기능을 구현할 수 있습니다.
핵심은 생성, 반복, 컬렉션과 같은 작업을 특정 컬렉션 클래스에 위임하는 것입니다. 왜냐하면 컬렉션 자체만이 이러한 작업을 완료하는 방법을 알고 있기 때문입니다.
function filter(f, xs) { const ret = new xs.constructor() for (const x of xs) { if (f(x)) { ret['@@transducer/step'](x) } } return ret }
filter(x => x % 2 === 1, range(10)) // [ 1, 3, 5, 7, 9 ]
filter(x => x > 3, new Set(range(10))) // Set (6) {4, 5, 6, 7, 8, 9}
구성하다
위의 맵과 필터를 함께 사용하면 몇 가지 문제가 발생할 수 있습니다.
range(10) .map(x => x + 1) .filter(x => x % 2 === 1) .slice(0, 3) // [ 1, 3, 5 ]
5개의 요소만 사용되지만 컬렉션의 모든 요소가 순회됩니다.
각 단계에서는 중간 컬렉션 개체가 생성됩니다.
우리는 Compose를 사용하여 이 로직을 다시 구현합니다
function compose(...fns) { return fns.reduceRight((acc, fn) => x => fn(acc(x)), x => x) }
합성을 지원하기 위해 맵, 필터 등의 기능을 카레 형태로 구현합니다.
function curry(f) { return (...args) => data => f(...args, data) }
var rmap = curry(map) var rfilter = curry(filter) function take(n, xs) { const ret = new xs.constructor() for (const x of xs) { if (n <pre class="brush:php;toolbar:false"> take(3, range(10)) // [ 0, 1, 2 ]
take(4, new Set(range(10))) // Set (4) {0, 1, 2, 3}
const takeFirst3Odd = compose( rtake(3), rfilter(x => x % 2 === 1), rmap(x => x + 1) ) takeFirst3Odd(range(10)) // [ 1, 3, 5 ]
지금까지 구현한 내용은 표현이 명확하고 간결하지만 런타임에는 낭비입니다.
함수의 형태
변신 로봇
curry 버전의 지도 기능은 다음과 같습니다.
const map = f => xs => ...
즉, map(x => ...)는 단일 매개변수 함수를 반환합니다.
const list = [1, 2, 3, 4, 5] list.map(x => x + 1) // [ 2, 3, 4, 5, 6 ]
하나의 매개변수로 함수를 쉽게 구성할 수 있습니다.
구체적으로 이들 함수의 입력은 '데이터', 출력은 가공된 데이터, 함수는 데이터 변환기(Transformer)이다.
function map(f, xs) { const ret = [] for (let i = 0; i <pre class="brush:php;toolbar:false"> map(x => x + 1, [1, 2, 3, 4, 5]) // [ 2, 3, 4, 5, 6 ]
function filter(f, xs) { const ret = [] for (let i = 0; i <p>Transformer는 단일 매개변수 함수로 함수 구성에 편리합니다.<br> </p> <pre class="brush:php;toolbar:false"> var range = n => [...Array(n).keys()]
감속기
리듀서는 더 복잡한 논리를 표현하는 데 사용할 수 있는 2개의 매개변수 함수입니다.
filter(x => x % 2 === 1, range(10)) // [ 1, 3, 5, 7, 9 ]
합집합
function map(f, xs) { const ret = new xs.constructor() // 1. construction for (const x of xs) { // 2. iteration ret['@@transducer/step'](f(x)) // 3. collection } return ret }
지도
Array.prototype['@@transducer/step'] = Array.prototype.push // [Function: push]
map(x => x + 1, [1, 2, 3, 4, 5]) // [ 2, 3, 4, 5, 6 ]
필터
Set.prototype['@@transducer/step'] = Set.prototype.add // [Function: add]
가져가다
take를 어떻게 구현하나요? Break와 유사한 기능을 가지려면 Reduce가 필요합니다.
map(x => x + 1, new Set([1, 2, 3, 4, 5])) // Set (5) {2, 3, 4, 5, 6}
function filter(f, xs) { const ret = new xs.constructor() for (const x of xs) { if (f(x)) { ret['@@transducer/step'](x) } } return ret }
filter(x => x % 2 === 1, range(10)) // [ 1, 3, 5, 7, 9 ]
변환기
드디어 우리의 주인공을 만나다
먼저 이전 지도 구현을 다시 검토하세요
filter(x => x > 3, new Set(range(10))) // Set (6) {4, 5, 6, 7, 8, 9}
위에서 언급한 배열(Array)에 의존하는 로직을 분리하여 감속기로 추상화하는 방법을 찾아야 합니다.
range(10) .map(x => x + 1) .filter(x => x % 2 === 1) .slice(0, 3) // [ 1, 3, 5 ]
구축도 사라지고, 반복도 사라지고, 요소의 수집도 사라졌습니다.
리듀서를 통해 지도에는 담당하는 로직만 포함됩니다.
필터를 다시 살펴보세요
function compose(...fns) { return fns.reduceRight((acc, fn) => x => fn(acc(x)), x => x) }
위의 rfilter와 rmap의 반환 유형을 확인하세요.
function curry(f) { return (...args) => data => f(...args, data) }
실제로는 매개변수와 반환 값이 모두 감소기인 변환기입니다.
Transformer는 구성 가능하므로 Transducer도 구성 가능합니다.
var rmap = curry(map) var rfilter = curry(filter) function take(n, xs) { const ret = new xs.constructor() for (const x of xs) { if (n <h2> 변환 및 변환 </h2> <p>그런데 변환기는 어떻게 사용하나요?<br> </p> <pre class="brush:php;toolbar:false"> take(3, range(10)) // [ 0, 1, 2 ]
take(4, new Set(range(10))) // Set (4) {0, 1, 2, 3}
리듀서를 이용하여 반복과 수집을 구현해야 합니다.
const takeFirst3Odd = compose( rtake(3), rfilter(x => x % 2 === 1), rmap(x => x + 1) ) takeFirst3Odd(range(10)) // [ 1, 3, 5 ]
이제 작동할 수 있으며 반복이 '주문형'이라는 점도 확인했습니다. 컬렉션에 100개의 요소가 있지만 처음 10개의 요소만 반복되었습니다.
다음으로 위의 논리를 함수로 캡슐화하겠습니다.
const map = f => xs => ...
type Transformer = (xs: T) => R
흐름
피보나치 생성기.
비동기 무한 피보나치 생성기와 같은 일종의 비동기 데이터 수집이 있다고 가정해 보겠습니다.
data ->> map(...) ->> filter(...) ->> reduce(...) -> result
function pipe(...fns) { return x => fns.reduce((ac, f) => f(ac), x) }
const reduce = (f, init) => xs => xs.reduce(f, init) const f = pipe( rmap(x => x + 1), rfilter(x => x % 2 === 1), rtake(5), reduce((a, b) => a + b, 0) ) f(range(100)) // 25
위 데이터 구조를 지원하는 into 함수를 구현해야 합니다.
참고로 코드의 배열 버전을 옆에 게시하세요.
type Transformer = (x: T) => T
구현 코드는 다음과 같습니다.
type Reducer = (ac: R, x: T) => R
수집 작업은 동일하지만 반복 작업은 다릅니다.
// add is an reducer const add = (a, b) => a + b const sum = xs => xs.reduce(add, 0) sum(range(11)) // 55
다른 데이터 구조에도 동일한 논리가 적용됩니다.
명령
주의 깊게 보시면 카레 기반의 Compose 버전과 리듀서 기반 버전의 매개변수 순서가 다르다는 것을 아실 수 있을 것입니다.
카레 버전
const list = [1, 2, 3, 4, 5] list.map(x => x + 1) // [ 2, 3, 4, 5, 6 ]
function map(f, xs) { const ret = [] for (let i = 0; i함수 실행은 오른쪽 결합입니다.
변환기 버전
map(x => x + 1, [1, 2, 3, 4, 5]) // [ 2, 3, 4, 5, 6 ]function filter(f, xs) { const ret = [] for (let i = 0; i <h2> 참조 </h2> <p>트랜스듀서 등장<br> 변환기 - Clojure 참조</p>
위 내용은 변환기: 강력한 기능 구성 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

JavaScript는 프론트 엔드 및 백엔드 개발에 사용할 수 있습니다. 프론트 엔드는 DOM 작업을 통해 사용자 경험을 향상시키고 백엔드는 Node.js를 통해 서버 작업을 처리합니다. 1. 프론트 엔드 예 : 웹 페이지 텍스트의 내용을 변경하십시오. 2. 백엔드 예제 : node.js 서버를 만듭니다.

Python 또는 JavaScript는 경력 개발, 학습 곡선 및 생태계를 기반으로해야합니다. 1) 경력 개발 : Python은 데이터 과학 및 백엔드 개발에 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 적합합니다. 2) 학습 곡선 : Python 구문은 간결하며 초보자에게 적합합니다. JavaScript Syntax는 유연합니다. 3) 생태계 : Python에는 풍부한 과학 컴퓨팅 라이브러리가 있으며 JavaScript는 강력한 프론트 엔드 프레임 워크를 가지고 있습니다.

JavaScript 프레임 워크의 힘은 개발 단순화, 사용자 경험 및 응용 프로그램 성능을 향상시키는 데 있습니다. 프레임 워크를 선택할 때 : 1. 프로젝트 규모와 복잡성, 2. 팀 경험, 3. 생태계 및 커뮤니티 지원.

서론 나는 당신이 이상하다는 것을 알고 있습니다. JavaScript, C 및 Browser는 정확히 무엇을해야합니까? 그들은 관련이없는 것처럼 보이지만 실제로는 현대 웹 개발에서 매우 중요한 역할을합니다. 오늘 우리는이 세 가지 사이의 밀접한 관계에 대해 논의 할 것입니다. 이 기사를 통해 브라우저에서 JavaScript가 어떻게 실행되는지, 브라우저 엔진의 C 역할 및 웹 페이지의 렌더링 및 상호 작용을 유도하기 위해 함께 작동하는 방법을 알게됩니다. 우리는 모두 JavaScript와 브라우저의 관계를 알고 있습니다. JavaScript는 프론트 엔드 개발의 핵심 언어입니다. 브라우저에서 직접 실행되므로 웹 페이지를 생생하고 흥미롭게 만듭니다. 왜 Javascr

Node.js는 크림 덕분에 효율적인 I/O에서 탁월합니다. 스트림은 메모리 오버로드를 피하고 큰 파일, 네트워크 작업 및 실시간 애플리케이션을위한 메모리 과부하를 피하기 위해 데이터를 점차적으로 처리합니다. 스트림을 TypeScript의 유형 안전과 결합하면 Powe가 생성됩니다

파이썬과 자바 스크립트 간의 성능과 효율성의 차이는 주로 다음과 같이 반영됩니다. 1) 해석 된 언어로서, 파이썬은 느리게 실행되지만 개발 효율이 높고 빠른 프로토 타입 개발에 적합합니다. 2) JavaScript는 브라우저의 단일 스레드로 제한되지만 멀티 스레딩 및 비동기 I/O는 Node.js의 성능을 향상시키는 데 사용될 수 있으며 실제 프로젝트에서는 이점이 있습니다.

JavaScript는 1995 년에 시작하여 Brandon Ike에 의해 만들어졌으며 언어를 C로 실현했습니다. 1.C Language는 JavaScript의 고성능 및 시스템 수준 프로그래밍 기능을 제공합니다. 2. JavaScript의 메모리 관리 및 성능 최적화는 C 언어에 의존합니다. 3. C 언어의 크로스 플랫폼 기능은 자바 스크립트가 다른 운영 체제에서 효율적으로 실행하는 데 도움이됩니다.

JavaScript는 브라우저 및 Node.js 환경에서 실행되며 JavaScript 엔진을 사용하여 코드를 구문 분석하고 실행합니다. 1) 구문 분석 단계에서 초록 구문 트리 (AST)를 생성합니다. 2) 컴파일 단계에서 AST를 바이트 코드 또는 기계 코드로 변환합니다. 3) 실행 단계에서 컴파일 된 코드를 실행하십시오.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

WebStorm Mac 버전
유용한 JavaScript 개발 도구

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경