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 문자열 교체 방법 및 FAQ에 대한 자세한 설명 이 기사는 JavaScript에서 문자열 문자를 대체하는 두 가지 방법 인 내부 JavaScript 코드와 웹 페이지의 내부 HTML을 탐색합니다. JavaScript 코드 내부의 문자열을 교체하십시오 가장 직접적인 방법은 대체 () 메소드를 사용하는 것입니다. str = str.replace ( "find", "replace"); 이 메소드는 첫 번째 일치 만 대체합니다. 모든 경기를 교체하려면 정규 표현식을 사용하고 전역 플래그 g를 추가하십시오. str = str.replace (/fi

이 튜토리얼은 사용자 정의 Google 검색 API를 블로그 또는 웹 사이트에 통합하는 방법을 보여 주며 표준 WordPress 테마 검색 기능보다보다 세련된 검색 경험을 제공합니다. 놀랍게도 쉽습니다! 검색을 Y로 제한 할 수 있습니다

그래서 여기 당신은 Ajax라는이 일에 대해 배울 준비가되어 있습니다. 그러나 정확히 무엇입니까? Ajax라는 용어는 역동적이고 대화식 웹 컨텐츠를 만드는 데 사용되는 느슨한 기술 그룹을 나타냅니다. 원래 Jesse J에 의해 만들어진 Ajax라는 용어

이 기사 시리즈는 2017 년 중반에 최신 정보와 새로운 예제로 다시 작성되었습니다. 이 JSON 예에서는 JSON 형식을 사용하여 파일에 간단한 값을 저장하는 방법을 살펴 봅니다. 키 값 쌍 표기법을 사용하여 모든 종류를 저장할 수 있습니다.

손쉬운 웹 페이지 레이아웃에 대한 jQuery 활용 : 8 에센셜 플러그인 jQuery는 웹 페이지 레이아웃을 크게 단순화합니다. 이 기사는 프로세스를 간소화하는 8 개의 강력한 JQuery 플러그인을 강조합니다. 특히 수동 웹 사이트 생성에 유용합니다.

핵심 포인트 JavaScript에서는 일반적으로 메소드를 "소유"하는 객체를 말하지만 함수가 호출되는 방식에 따라 다릅니다. 현재 객체가 없으면 글로벌 객체를 나타냅니다. 웹 브라우저에서는 창으로 표시됩니다. 함수를 호출 할 때 이것은 전역 객체를 유지하지만 객체 생성자 또는 그 메소드를 호출 할 때는 객체의 인스턴스를 나타냅니다. call (), apply () 및 bind ()와 같은 메소드를 사용 하여이 컨텍스트를 변경할 수 있습니다. 이 방법은 주어진이 값과 매개 변수를 사용하여 함수를 호출합니다. JavaScript는 훌륭한 프로그래밍 언어입니다. 몇 년 전,이 문장은있었습니다

JQuery는 훌륭한 JavaScript 프레임 워크입니다. 그러나 어떤 도서관과 마찬가지로, 때로는 진행 상황을 발견하기 위해 후드 아래로 들어가야합니다. 아마도 버그를 추적하거나 jQuery가 특정 UI를 달성하는 방법에 대해 궁금한 점이 있기 때문일 것입니다.

이 게시물은 Android, BlackBerry 및 iPhone 앱 개발을위한 유용한 치트 시트, 참조 안내서, 빠른 레시피 및 코드 스 니펫을 컴파일합니다. 개발자가 없어서는 안됩니다! 터치 제스처 참조 안내서 (PDF) Desig를위한 귀중한 자원


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

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

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)
