댓글 검색 목록

[javascript] Javascript 배열 함수 안내서 : 작업에 가장 강력한 도구를 선택해야 하는 이유

페이지 정보

작성자 운영자 작성일 20-07-17 16:33 조회 701 댓글 0

배열 함수와 최소 전력 규칙


https://jesseduffield.com/array-functions-and-the-rule-of-least-power/ 


e8JqZPe.png 



가장 작은 힘의 법칙 


1998 년에 월드 와이드 웹의 발명가인 Tim Berners-Lee는 최소 전력 원칙(the Principle of Least Power)을 만들었습니다.


1960 ~ 80 년대의 컴퓨터 과학은 가능한 한 강력한 언어를 만들기 위해 많은 노력을 기울였습니다. 오늘날 우리는 가장 강력한 솔루션이 아니라 가장 강력한 솔루션을 선택하는 이유를 이해해야 합니다. 


2006 년에 W3C는이 원칙을 최소한의 힘의 규칙(Rule of Least Power)으로 체계화했습니다.


언어의 계산 능력과 해당 언어의 프로그램이 수행하는 작업을 결정하는 능력 간에는 중요한 상충 관계가 있습니다.


덜 강력한 언어로 제약 조건, 관계 및 처리 명령을 표현하면 정보를 재사용 할 수 있는 유연성이 향상됩니다. 언어가 적을수록 해당 언어로 저장된 데이터로 더 많은 일을 할 수 있습니다. 


실제로 Berners-Lee는 이 규칙에 따라 HTML을 선의의 언어로 만들지 않기로 결정했습니다.


다른 프로그램에서 다른 작업을 수행하기를 원했기 때문에 HTML을 프로그래밍 언어가 아닌 HTML로 선택했습니다. 다르게 표시, 목차 추출, 색인 작성 등. 


Least Power의 규칙은 언어 기능이 아닌 프로그래밍 언어 자체를 대상으로 했지만 동일한 아이디어가 여전히 적용된다고 생각합니다. 코드가 강력하지 않을수록 추론하기가 더 쉽습니다.


배열 함수 


따라서 일부 사람들은 .filter, .map 및 .reduce와 같은 '함수형'배열 함수가 조잡한 for-loop 대안에 비해 강력하다고 말합니다. 나는 그 반대라고 말할 것입니다 : 그것들은 훨씬 덜 강력합니다. 그것이 핵심입니다.


의심 할 여지없이,이 함수들을 'powerful'이라고 부르는 사람들은 아마도 그들의 힘 (예 : array.map (...). filter (...)을 호출 할 수 있거나 병렬 처리를 통해 활성화 된 힘을 가리킬 수도 있습니다) 또는 콜백을 일급 함수 변수에 할당함으로써 얻을 수 있는 힘.


그러나 개별적으로 고려할 때 이러한 기능의 힘이 실제로 설계 상 어떻게 낮은 지에 주의를 기울이고 싶습니다.


다음은 가장 강력한 (for-loop)에서 가장 강력한 (.some / .every)로 이동하는 일반적인 자바 스크립트 배열 함수를 순서대로 정렬하는 다이어그램입니다.


EvOGL7B.png 


배열 함수 요약 



내가 의미하는 바를 강력하게 설명하기 전에 다음은 다양한 접근 방식이 실제로 무엇인지 간략하게 요약 한 것입니다.


  • for-loop : 일반적으로 루프 내부에 부작용을 발생 시키기 위해 코드 덩어리를 반복합니다 (예 : 배열에 추가)
  • .forEach : 배열의 각 요소를 반복하고 각 반복에서 해당 요소로 무언가를 수행하십시오. 다시 말하지만, 일반적으로 어떤 시점에서 부작용을 만들기 위해.

여기에서 부작용은 강력히 권장하지 않습니다


  • .reduce : 왼쪽에서 오른쪽으로 배열을 반복하여 시작시 명시 적으로 초기화 된 일부 값을 누적 합니다. 각 반복에서 현재 배열 항목을 가져와 누산기의 새 값을 반환합니다 (최종을 반환 할 때까지) 끝에 가치)
  • .map : 배열의 각 원본 항목에 대해 출력 배열의 해당 색인에 배치 할 원본 항목의 함수로 새 항목을 반환합니다.
  • .filter : 왼쪽에서 오른쪽으로, 배열의 각 항목에 대해 조건을 만족하는 경우 출력 배열에 포함 시킵니다.
  • .find : 왼쪽에서 오른쪽으로, 일부 조건을 만족하는 배열의 첫 번째 항목을 반환
  • .every : 배열의 모든 항목이 특정 조건을 만족하면 true를, 그렇지 않으면 false를 반환합니다.
  • .some : 배열의 어떤 항목이 어떤 조건을 만족하면 true를, 그렇지 않으면 false를 반환합니다.

이 글은 각각이 하는 일을 설명하고 사용할 것을 고르는 것에 대한 내용이 아닙니다. 좋은 참조를 위해 여기를 십시오


강력한 의미는 무엇입니까? 


Tim Berners-Lee의 주화를 피기 백하고 있지만 '강력한'이라고 말하면 실제로 '유연성'을 의미합니다. 마찬가지로 이 함수는 몇 개의 사용 사례를 만족시킬 수 있습니까? 특히, 함수 B를 자체 용어로 구현할 수 있다면 함수 A를 함수 B보다 강력한 것으로 정의하고 함수 B가 할 수 없는 다른 작업도 수행합니다. *


내 정의 (범용이라고 주장하지는 않음)는 for-loop를 통해 .forEach를 구현할 수 있기 때문에 for-loop가 .forEach보다 강력합니다. 예를 들면 다음과 같습니다.


const forEach = (array, callback) => {

  for (i = 0; i < array.length; i++) {

    callback(array[i])

  }

}


forEach([1,2,3], a => console.log(a))

> 1

> 2

> 3


[1,2,3].forEach(a => console.log(a))

> 1

> 2

> 3


따라서 .forEach가 무엇을 할 수 있더라도 for-loop는 더 많은 일을 할 수 있습니다.


마찬가지로 .reduce는 다음과 같이 .forEach로 구현할 수 있습니다.


const reduce = (array, callback, initialValue) => {

  let result = initialValue


  array.forEach((item) => {

    result = callback(result, item)

  })


  return result

}


reduce([1,2,3], (acc, curr) => acc + curr, 0)

> 6


[1,2,3].reduce((acc, curr) => acc + curr, 0)

> 6


그리고 계속해서 바닥까지 갑니다 :


const some = (array, callback) => array.find(callback) !== undefined


특히, 우리의 사용자 정의 일부는 ECMASCript뿐만 아니라 정의되지 않은 값을 처리하지 않지만 아이디어를 얻습니다.


가장 강력한 함수를 선택하십시오


왜 모든 것에 for 루프를 사용하지 않습니까? 그렇게 하면 배열의 항목을 반복하는 한 가지 방법 만 기억하면 됩니다. 그 이유는 수류탄을 사용하여 모기를 죽이지 않는 것과 같은 이유입니다. 수류탄은 불법이며 암시장 제품은 공급 업체의 위험을 보조 하기 위해 표시됩니다.


그러나 가장 강력한 도구를 선택해야 하는 여러 가지 이유가 있지만 가장 중요한 두 가지 이유는 다음과 같습니다.


  • 오류 가능성 감소
  • 다른 사람들에 의한 쉬운 이해

오류의 기회 감소 


여전히 작업을 수행 할 수 있는 가장 강력한 도구는 오류 가능성이 가장 적은 도구입니다. 숫자 배열이 있고 배열의 각 항목을 두 배로 늘린 결과를 반환하려는 상황을 고려하십시오.


const myArray = [1,2,3]


// with `.map`

resultWithMap = myArray.map(item => item * 2)

> [2,4,6]


// with a for-loop

let resultWithLoop = []

for (i = 0; i < myArray.length-1; i++) {

  resultWithLoop.push(array[i] * 2)

}

resultWithLoop

> [2,4]


이봐, 대체 뭐야? 내 resultWithLoop에 항목이 없는 이유는 무엇입니까? 인덱스를 0에서 시작하고 한 번에 하나씩 만 증가 시켰으며 인덱스 myArray.length에 요소를 포함 시키지 않으면 범위를 벗어난 오류가 발생하지 않도록 합니다.


아 잠깐, for 루프에서 <는 <=이어야 합니다 (또는 myArray.length-1에서 -1을 제거 할 수 있습니다). 내 실수.


for-loop는 너무 강력하여 실제로 사용하는 것을 신경 쓰지 않습니다. 실제로 최종 요소를 제외하고 싶을 수도 있습니다. 어떻게 알 수 있습니까? 운 좋게도 우리는 이것을 일찍 잡았지만 수류탄 핀이 없거나 유실 되었든 실수를 깨달을 때까지 이미 너무 늦었습니다.


.map이 여기에서 적절한 선택 인 이유는 목록의 각 항목을 통한 루핑 제어 흐름을 숨기는 추상화이기 때문에 잘못 이해하는 것이 불가능하기 때문입니다. .map을 사용하면 결과에 원래 맵만큼 많은 요소가 있으며 출력 배열의 각 요소는 입력 배열의 해당 요소에만 해당됩니다 **.


다른 사람들의 쉬운 이해 


위의 for-loop 접근법과 .map 접근법을 비교하면 독자로 구문 분석하기가 더 쉽습니다. for-loops에 대해서만 잘 알고 있다면 그것을 선택 하겠지만 오늘날 프로그래밍 언어에서 .map의 편재성을 감안할 때 아마도 배울 때입니다. 두 가지 모두에 익숙한 사람들에게는 .map 접근 방식이 훨씬 읽기 쉽습니다.


  • for 루프에서 i 변수가 조작되는 방식을 완전히 읽을 필요는 없습니다. 추상화 되어 있기 때문입니다.
  • 출력 형태가 무엇인지 알 것입니다.
  • 각 반복에서 원래 변수가 변경되는지 여부에 대해 걱정할 필요가 없습니다.


.map에 전달 된 콜백 함수를 보지 않아도 결과에서 기대할 수 있는 것에 대해 많은 것을 알고 있습니다. for 루프에 대해서도 마찬가지입니다.


마찬가지로, 과일이 많이 있고 사과가 들어 있는지 알고 싶습니다. 몇 가지 접근 방식이 있습니다.


const fruits = ['orange', 'pear', 'apple', 'apple', 'peach']


const hasAppleViaFilter = fruits.filter(fruit => fruit === 'apple').length > 0

> true


const hasAppleViaFind = fruits.find(fruit => fruit === 'apple') !== undefined

> true


const hasAppleViaSome = fruits.some(fruit => fruit === 'apple')

> true


각 접근 방식은 전력을 낮추는 순서로 정렬됩니다. .some이 눈에서 가장 쉬운 것을 주목하십시오. .some을 보자 마자 hasAppleViaSome에 콜백 fruit => fruit === 'apple'을 기반으로 부울 값이 할당됩니다. 필터 접근 방식에서는 원래 배열 과일의 하위 집합으로 배열을 만들고 있다는 사실을 정신적으로 저장해야 하며 그 길이를 확인하고 0과 비교합니다. 그 모든 것을 구문 분석 한 후에 만 ​​실제 암시 적 의도를 깨닫게 됩니다. 이는 .some 메소드의 명시 적 의도와 동일합니다.


이것들은 단지 작은 예이지만, 내부에 많은 코드가 있는 큰 털이 많은 콜백이 있으면 독자는 여전히 .some에 대한 호출임을 알 수 있으며 모든 콜백이 true 또는 false를 반환한다는 것을 확신 할 수 있습니다. 이를 통해 독자의 기대치를 교정하고 콜백 내부에서 발생하는 상황을 보다 쉽게 ​​처리 할 수 ​​있습니다.


const hasAppleViaContrivedSome = fruits.some(fruit => {

  if (typeof fruit !== 'string') {

    return false

  } 


  if (fruit === 'pear') {

    return false

  } 


  if (fruit === 'orange') {

    return false

  } 


  if (fruit === 'forbidden fruit') {

    return false

  }


  if (fruit.substring(1, 4) === 'pple') {

    return fruit === 'apple'

  }


  return false

})


반면에 누군가가 코드를 발견하고 .some 호출처럼 사소한 것을 수행하는 데 사용되는 강력한 기능을 발견하면 일반적으로 유지하는 장소에서 수류탄을 발견 한 시간보다 혼란스럽습니다. 파리가 흔들렸다.



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.