Ответ 1
Сначала, согласно вашей ссылке, textfile
создается как
val textFile = sc.textFile("README.md")
так что textfile
является RDD[String]
, что означает гибкий распределенный набор данных типа String
. API для доступа очень похож на API обычных коллекций Scala.
Итак, что делает это map
?
Представьте, что у вас есть список String
и вы хотите преобразовать его в список Ints, представляющий длину каждой строки.
val stringlist: List[String] = List("ab", "cde", "f")
val intlist: List[Int] = stringlist.map( x => x.length )
Метод map
ожидает функцию. Функция, которая идет от String => Int
. С помощью этой функции каждый элемент списка преобразуется. Таким образом, значение intlist равно List( 2, 3, 1 )
Здесь мы создали анонимную функцию из String => Int
. Это x => x.length
. Можно даже написать функцию более явную как
stringlist.map( (x: String) => x.length )
Если вы используете запись выше, вы можете
val stringLength : (String => Int) = {
x => x.length
}
val intlist = stringlist.map( stringLength )
Итак, здесь совершенно очевидно, что stringLength является функцией от String
до Int
.
Примечание: В общем, map
- это то, что составляет так называемый Functor. Пока вы предоставляете функцию от A = > B, map
функтора (здесь List), вы можете использовать эту функцию также для перехода от List[A] => List[B]
. Это называется подъем.
Ответы на ваши вопросы
Что такое переменная "строка"?
Как упоминалось выше, line
является входным параметром функции line => line.split(" ").size
Более явный
(line: String) => line.split(" ").size
Пример: Если line
является "hello world", функция возвращает 2.
"hello world"
=> Array("hello", "world") // split
=> 2 // size of Array
Как передается значение a, b?
reduce
также ожидает функцию от (A, A) => A
, где A
- тип вашего RDD
. Позволяет называть эту функцию op
.
Что делает reduce
. Пример:
List( 1, 2, 3, 4 ).reduce( (x,y) => x + y )
Step 1 : op( 1, 2 ) will be the first evaluation.
Start with 1, 2, that is
x is 1 and y is 2
Step 2: op( op( 1, 2 ), 3 ) - take the next element 3
Take the next element 3:
x is op(1,2) = 3 and y = 3
Step 3: op( op( op( 1, 2 ), 3 ), 4)
Take the next element 4:
x is op(op(1,2), 3 ) = op( 3,3 ) = 6 and y is 4
Результат здесь - сумма элементов списка, 10.
Примечание: обычно reduce
вычисляет
op( op( ... op(x_1, x_2) ..., x_{n-1}), x_n)
Полный пример
Во-первых, текстовый файл является RDD [String], скажем
TextFile
"hello Tyth"
"cool example, eh?"
"goodbye"
TextFile.map(line => line.split(" ").size)
2
3
1
TextFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
3
Steps here, recall `(a, b) => if (a > b) a else b)`
- op( op(2, 3), 1) evaluates to op(3, 1), since op(2, 3) = 3
- op( 3, 1 ) = 3