[SCALA] (왼쪽 / 오른쪽) 배, 줄이거 나 스캔?
SCALA(왼쪽 / 오른쪽) 배, 줄이거 나 스캔?
언제 reduceLeft, reduceRight, foldLeft, foldRight, scanLeft 또는 scanRight을 사용해야합니까?
나는 그들의 차이의 직관 / 개요를 원하는 - 아마도 몇 가지 간단한 예제와 함께.
해결법
-
==============================
1.일반적으로, 모든 6 개 배 기능 집합의 각 요소에 이진 연산자를 적용한다. 각 단계의 결과는 (이진 연산자의 두 개의 인자들 중 하나에 대한 입력으로) 다음 단계로 전달된다. 이 방법으로 우리는 결과를 쌓아 수 있습니다.
일반적으로, 모든 6 개 배 기능 집합의 각 요소에 이진 연산자를 적용한다. 각 단계의 결과는 (이진 연산자의 두 개의 인자들 중 하나에 대한 입력으로) 다음 단계로 전달된다. 이 방법으로 우리는 결과를 쌓아 수 있습니다.
reduceLeft 및 reduceRight은 하나의 결과를 쌓아.
foldLeft 및 foldRight은 시작 값을 사용하는 하나의 결과를 쌓아.
scanLeft 및 scanRight은 시작 값을 사용하여 중간 누적 결과 집합을 쌓아.
왼쪽 및 전달에서 ...
ABC 요소의 컬렉션 이진 연산자 우리가 다른 스크롤 기능이 무엇 탐험 추가 (C A에서) 수집 좌측 요소로부터 전방으로 이동할 때 :
val abc = List("A", "B", "C") def add(res: String, x: String) = { println(s"op: $res + $x = ${res + x}") res + x } abc.reduceLeft(add) // op: A + B = AB // op: AB + C = ABC // accumulates value AB in *first* operator arg `res` // res: String = ABC abc.foldLeft("z")(add) // with start value "z" // op: z + A = zA // initial extra operation // op: zA + B = zAB // op: zAB + C = zABC // res: String = zABC abc.scanLeft("z")(add) // op: z + A = zA // same operations as foldLeft above... // op: zA + B = zAB // op: zAB + C = zABC // res: List[String] = List(z, zA, zAB, zABC) // maps intermediate results
오른쪽에서 뒤로 ...
우리가 RIGHT 요소로 시작하고 우리의 바이너리 연산자는 결과를 축적에 우리가 지금 두 번째 인수를 알 수 있습니다 (A와 C에서) 뒤로 가면 (운영자가 동일, 우리는 단지 자신의 역할을 명확하게하기 위해 인수 이름을 전환 ) :
def add(x: String, res: String) = { println(s"op: $x + $res = ${x + res}") x + res } abc.reduceRight(add) // op: B + C = BC // op: A + BC = ABC // accumulates value BC in *second* operator arg `res` // res: String = ABC abc.foldRight("z")(add) // op: C + z = Cz // op: B + Cz = BCz // op: A + BCz = ABCz // res: String = ABCz abc.scanRight("z")(add) // op: C + z = Cz // op: B + Cz = BCz // op: A + BCz = ABCz // res: List[String] = List(ABCz, BCz, Cz, z)
.
왼쪽 및 전달에서 ...
대신하면 우리는 우리가 우리의 이항 연산자 마이너스의 첫 번째 인수의 고해상도를 통해 결과를 쌓아 올린 것 모음의 왼쪽 요소부터 감산에 의해 어떤 결과를 해제 쌓아했다 :
val xs = List(1, 2, 3, 4) def minus(res: Int, x: Int) = { println(s"op: $res - $x = ${res - x}") res - x } xs.reduceLeft(minus) // op: 1 - 2 = -1 // op: -1 - 3 = -4 // de-cumulates value -1 in *first* operator arg `res` // op: -4 - 4 = -8 // res: Int = -8 xs.foldLeft(0)(minus) // op: 0 - 1 = -1 // op: -1 - 2 = -3 // op: -3 - 3 = -6 // op: -6 - 4 = -10 // res: Int = -10 xs.scanLeft(0)(minus) // op: 0 - 1 = -1 // op: -1 - 2 = -3 // op: -3 - 3 = -6 // op: -6 - 4 = -10 // res: List[Int] = List(0, -1, -3, -6, -10)
오른쪽에서 뒤로 ...
하지만 지금은 xRight 변화를 조심해! xRight 변동의 (축소) 누적 값이 우리의 이진 연산자 마이너스의 제 파라미터 입술에 전달되어 기억
def minus(x: Int, res: Int) = { println(s"op: $x - $res = ${x - res}") x - res } xs.reduceRight(minus) // op: 3 - 4 = -1 // op: 2 - -1 = 3 // de-cumulates value -1 in *second* operator arg `res` // op: 1 - 3 = -2 // res: Int = -2 xs.foldRight(0)(minus) // op: 4 - 0 = 4 // op: 3 - 4 = -1 // op: 2 - -1 = 3 // op: 1 - 3 = -2 // res: Int = -2 xs.scanRight(0)(minus) // op: 4 - 0 = 4 // op: 3 - 4 = -1 // op: 2 - -1 = 3 // op: 1 - 3 = -2 // res: List[Int] = List(-2, 3, -1, 4, 0)
마지막 목록 (-2, 3, -1, 4, 0) 아마 당신은 직관적으로 기대하는 것입니다!
보시다시피, 당신은 당신의 foldX 단순히 대신 scanX을 실행하고 각 단계에서의 누적 결과를 디버깅에 의해 무엇을하고 있는지 확인할 수 있습니다.
-
==============================
2.일반적으로 왼쪽에있는 데이터를 축적하여 FOLD, SCAN 방법은 작동 줄이고 RIGHT 변수를 변경 계속. 그들 사이의 가장 큰 차이점은 FOLD가 감소입니다 : -
일반적으로 왼쪽에있는 데이터를 축적하여 FOLD, SCAN 방법은 작동 줄이고 RIGHT 변수를 변경 계속. 그들 사이의 가장 큰 차이점은 FOLD가 감소입니다 : -
항상 즉, 사용자 정의 시작 값 시드 값으로 시작됩니다 접습니다. 배는 시드 값을 돌려주기 때문에 어디 모음이 비어있는 경우 예외가 발생합니다 줄일 수 있습니다. 항상 단일 값을 발생합니다.
스캔이 좌측 또는 우측의 항목 중 일부의 처리 순서에 사용되는, 우리는 후속 계산에서 이전의 결과를 사용할 수있다. 그게 우리가 항목을 스캔 할 수 있음을 의미합니다. 항상 컬렉션을 발생합니다.
아래에 언급 된 코드에 대한 출력의 일부는 다음과 같습니다 -
번호 목록 스캐닝 동작을 이용하여 (-1,0,1,2, -2) 목록 (시드 값 0을 사용)
감소 문자열리스트의리스트를 조작하여 배 ( "A", "B", "C", "D", "E")
코드 :
object ScanFoldReduce extends App { val list = List("A","B","C","D","E") println("reduce (a+b) "+list.reduce((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" ") a+b })) println("reduceLeft (a+b) "+list.reduceLeft((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" ") a+b })) println("reduceLeft (b+a) "+list.reduceLeft((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" " ) b+a })) println("reduceRight (a+b) "+list.reduceRight((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("reduceRight (b+a) "+list.reduceRight((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" ") b+a })) println("scan "+list.scan("[")((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("scanLeft (a+b) "+list.scanLeft("[")((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("scanLeft (b+a) "+list.scanLeft("[")((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" " ) b+a })) println("scanRight (a+b) "+list.scanRight("[")((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("scanRight (b+a) "+list.scanRight("[")((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" " ) b+a })) //Using numbers val list1 = List(-2,-1,0,1,2) println("reduce (a+b) "+list1.reduce((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" ") a+b })) println("reduceLeft (a+b) "+list1.reduceLeft((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" ") a+b })) println("reduceLeft (b+a) "+list1.reduceLeft((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" " ) b+a })) println(" reduceRight (a+b) "+list1.reduceRight((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println(" reduceRight (b+a) "+list1.reduceRight((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" ") b+a })) println("scan "+list1.scan(0)((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("scanLeft (a+b) "+list1.scanLeft(0)((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b })) println("scanLeft (b+a) "+list1.scanLeft(0)((a,b)=>{ print("{"+a+","+b+"}=>"+ (b+a)+" " ) b+a })) println("scanRight (a+b) "+list1.scanRight(0)((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) a+b})) println("scanRight (b+a) "+list1.scanRight(0)((a,b)=>{ print("{"+a+","+b+"}=>"+ (a+b)+" " ) b+a})) }
from https://stackoverflow.com/questions/17408880/reduce-fold-or-scan-left-right by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 나는 런타임에 변수의 유형을 얻으려면 (0) | 2019.11.04 |
---|---|
[SCALA] 어떻게 동적 작업을 입력 기능과 사용 방법에? (0) | 2019.11.04 |
[SCALA] MatchError 스파크 2.0 벡터 열에 액세스 할 때 (0) | 2019.11.04 |
[SCALA] 한 인수 함수를 호출 할 때 왜 그리고 어떻게 스칼라 특별히 튜플을 치료한다? (0) | 2019.11.04 |
[SCALA] 스칼라는 최소한의 기능을 강조 (0) | 2019.11.04 |