2013-06-16 6 views
2

Кто-нибудь знает, как сравнивать последовательные записи в scalding при создании схемы. Я смотрю на уроке 6, и предположим, что я хочу, чтобы напечатать возраст человека, если данные в звукозаписывающей # 2 больше, чем запись # 1 (для всех записей)обжиг сравнения последовательных записей

, например:

R1: John 30 
R2: Kim 55 
R3: Mark 20 

if Rn.age > R(n-1).age the output ... which will result to R2: Kim 55 

EDIT : Глядя на код, я только что понял, что это перечисление Scala, поэтому мой вопрос заключается в том, как сравнивать записи в scala перечислении?

class Tutorial6(args : Args) extends Job(args) { 
    /** When a data set has a large number of fields, and we want to specify those fields conveniently 
    in code, we can use, for example, a Tuple of Symbols (as most of the other tutorials show), or a List of Symbols. 
    Note that Tuples can only be used if the number of fields is at most 22, since Scala Tuples cannot have more 
    than 22 elements. Another alternative is to use Enumerations, which we show here **/ 

    object Schema extends Enumeration { 
    val first, last, phone, age, country = Value // arbitrary number of fields 
    } 

    import Schema._ 

    Csv("tutorial/data/phones.txt", separator = " ", fields = Schema) 
    .read 
    .project(first,age) 
    .write(Tsv("tutorial/data/output6.tsv")) 
} 

ответ

2

Кажется, неявное преобразование из перечисления # Значение отсутствует, так что вы можете определить сами:

import cascading.tuple.Fields 
implicit def valueToFields(v: Enumeration#Value): Fields = v.toString 

object Schema extends Enumeration { 
    val first, last, phone, age, country = Value // arbitrary number of fields 
} 

import Schema._ 

var current = Int.MaxValue 

Csv("tutorial/data/phones.txt", separator = " ", fields = Schema) 
    .read 
    .map(age -> ('current, 'previous)) { a: String => 
    val previous = current 
    current = a.toInt 
    current -> previous 
    } 
    .filter('current, 'previous) { age: (Int, Int) => age._1 > age._2 } 
    .project(first, age) 
    .write(Tsv("tutorial/data/output6.tsv")) 

В конце концов, мы ожидаем, что результат будет таким же, как и у:

Csv("tutorial/data/phones.txt", separator = " ", fields = Schema) 
    .read 
    .map((new Fields("age"), (new Fields("current", "previous"))) { a: String => 
    val previous = current 
    current = a.toInt 
    current -> previous 
    } 
    .filter(new Fields("current", "previous")) { age: (Int, Int) => 
    age._1 > age._2 
    } 
    .project(new Fields("first", "age")) 
    .write(Tsv("tutorial/data/output6.tsv")) 

Неявные преобразования, обеспечиваемые обжиганием, позволяют писать более короткие версии этих new Fields(...).

Непосредственное преобразование - это просто представление, которое будет использоваться компилятором при передаче аргументов, которые не относятся к ожидаемому типу, но могут быть преобразованы в соответствующий тип этим представлением. Например, поскольку map() ожидает пару Fields, пока вы передаете пару символов, Scala будет искать неявное преобразование от Symbol -> Symbol до Fields -> Fields. Краткое пояснение по мнениям можно найти here.

Scalding 0.8.5 ввел преобразования из продукта Eumeration#Value в Fields, но пропал конверсий из пары значений. Фирма develop теперь также предоставляет последнюю.

+0

работал чудесно. Большое спасибо. Не могли бы вы объяснить или показать мне, где я могу узнать больше об этой строке? Неявное значение defToFields (v: Enumeration # Value): Fields = v.toString " – CruncherBigData

+0

Отредактировано для добавления некоторых деталей и ссылки на http: //www.scala -lang.org/node/130, который дает обзор неявных преобразований. –

+0

Отличное объяснение, большое спасибо за ваши усилия. – CruncherBigData

Смежные вопросы