2010-05-18 19 views
5

Sözcüklerin bir listesini ve ilişkili etiketlerinin bir listesini bende bulabilirsiniz. Her iki dizin üzerinde aynı anda (eşleştirilmiş dizin) her bir dizinlenmiş tuple bir .NET işlevine girdi olarak yinelemek istiyorum. Bu en iyi yolu (Çalışır, ama bana doğal gelmiyor) mi:f # C# kitaplığından işlev kullanılarak iki dizi üzerinde yineleme

let taggingModel = SeqLabeler.loadModel(lthPath + 
         "models\penn_00_18_split_dict.model"); 
let lemmatizer = new Lemmatizer(lthPath + "v_n_a.txt") 
let input = "the rain in spain falls on the plain" 

let words = Preprocessor.tokenizeSentence(input) 
let tags = SeqLabeler.tagSentence(taggingModel, words) 
let lemmas = Array.map2 (fun x y -> lemmatizer.lookup(x,y)) words tags 

cevap

13

Kodunuz bana oldukça iyi görünüyor - bunun çoğu bazı yükleme ve başlatma ile ilgilenen, bu yüzden pek bir şey yok Bu parçayı basitleştirmek için yapabilirsin. lookup fonksiyonu, argüman olarak var bir demet alır

let lemmas = Seq.zip words tags 
      |> Seq.map (fun (x, y) -> lemmatizer.lookup (x, y)) 

Süresi: zip fonksiyonu eşleşen indisli elemanları çiftleri içeren bir tek içine iki dizilerini birleştirir - Alternatif olarak Array.map2 için, Seq.zipSeq.map ile birlikte kullanabilir , yazabilirsiniz:

// standard syntax using the pipelining operator 
let lemmas = Seq.zip words tags |> Seq.map lemmatizer.lookup 

// .. an alternative syntax doing exactly the same thing 
let lemmas = (words, tags) ||> Seq.zip |> Seq.map lemmatizer.lookup 

ikinci versiyonunda kullanılan ||> operatör th anlamına iki değerlerini içeren bir demet alır ve iki bağımsız değişken olarak sağ tarafta işleve iletir (a, b) ||> f, f a b anlamına gelir. |> işleci, yalnızca solda tek bir değer alır, bu nedenle (a, b) |> f, f (a, b) anlamına gelir (bu işlev, f işlevinin yerine iki, alan ayrımı, parametreler yerine bekleniyorsa çalışır). Sonunda bir dizi olmasını lemmas gerekiyorsa

, sen işlem boru (bütün Seq fonksiyonları IEnumerable<T> karşılık dizileri, çalışmak)

Bir daha alternatif sonuna Array.ofSeq eklemeniz gerekir dizi ifadeleri ya da değil kullanılıp kullanılmayacağı

let lemmas = [| for wt in Seq.zip words tags do // wt is tuple (string * string) 
        yield lemmatizer.lookup wt |] 

- bu sadece kişisel bir tercih: sekans ifadeler kullanmayı edilir (bunu neye ihtiyacınız var doğrudan eğer bir diziyi oluşturmak için [| .. |] kullanabilirsiniz). İlk seçenek bu durumda daha özlü görünmektedir, ancak dizi ifadeleri, kısmi işlev uygulaması gibi (daha kısa sürümde Seq.map)

+2

+1 ||> işleci gibi şeylere daha az aşina olan kişiler için daha okunabilir olabilir! –

+0

harika. neden gerekli? neden çalışmıyor –

+1

'||>' ile ilgili bazı açıklamalar ekledim - kısaca - sağdaki işleve iki parametre iletmenize izin verirken, '|' 'sadece bir parametre belirtir (' Seq.zip' iki parametreyi alır). –