2011-12-15 15 views
13

Tamamen işlevsel bir şekilde bir javascript ışın döküm noktası-çokgen algoritması uyguluyorum (bunun arkasında belirli bir neden yok).Haskell'in unzip'inin js versiyonunu tamamen işlevsel bir şekilde uygulamak mümkün mü?

2 boyutlu bir diziden iki dizi almak gerektiğinden takılıp kaldım (bir liste listesi çoğaltmak); Haskell'in unzip'a benzeyen bir şey.

[[a,b],[c,d],[e,f]] gibi bir şeyden başlayarak, [[a,c,e],[b,d,f]] prosedürural stil yineleme kullanmadan elde etmek mümkün mü?

(Ben önemsiz bir soru olduğunu biliyorum, ve ben sadece prosedür işlevi uygulamak ve bu konuda unutabilir ama bir çözüm olsaydı ben merak ettiğim)


DÜZENLEME: netleştirmek için, zip ve unzip'u nasıl uygulayacağımı biliyorum: for döngüler ve değişken yeniden atamalar olmadan bunları uygulamak mümkün olabilirdi.

+0

JavaScript ve Haskell'in bir listenin temsili arasındaki fark göz önüne alındığında, bunlar aynı şekilde uygulanamaz. Haskell, listeleri tek tek bağlı değişmez bir yapı olarak uygular. Java, listeleri değiştirilebilir bir dizi olarak uygular. İlk için yineleme ve desen eşleştirmesi kullanın. İkincisi için, döngüler ve dizinler için kullanın. –

+0

Hm, Js'nin listelerinin olmadığını biliyorum. Kısıtlı bir alanda, belirli bir işleve atıfta bulundum - "sonsuz diziler" (lulz) veya benzeri üzerinde çalışmak için ona ihtiyacım yoktu. – cbrandolino

cevap

6

Unzip'iniz sadece bir zip ancak çoklu argümanlar ile. Çoğu kişinin sadece aynı işlevi kullanmadığı tek neden, çoğu zaman zip dizinin bir dizi yerine değişkenlerin argümanı listesini almasıdır, bu nedenle unzip işlevinde apply ile bir şeyleri açmanız gerekir.

Dojo'nun yılında

, ben kullanıyorum kütüphane, onlar zip uygulamak ve daha Python zip gibi ve daha az Haskell gibi yani birden fazla argüman alır zip

unzip: function(/*Array*/ a){ 
    // summary: similar to dojox.lang.functional.zip(), but takes 
    // a single array of arrays as the input. 
    // description: This function is similar to dojox.lang.functional.zip() 
    // and can be used to unzip objects packed by 
    // dojox.lang.functional.zip(). It is here mostly to provide 
    // a short-cut for the different method signature. 

    return df.zip.apply(null, a); 
} 

zip: function(){ 
    // summary: returns an array of arrays, where the i-th array 
    // contains the i-th element from each of the argument arrays. 
    // description: This is the venerable zip combiner (for example, 
    // see Python documentation for general details). The returned 
    // array is truncated to match the length of the shortest input 
    // array. 
    var n = arguments[0].length, 
     m = arguments.length, 
     i = 1, 
     t = new Array(n), 
     j, 
     p; 
    for(; i < m; n = Math.min(n, arguments[i++].length)); 
    for(i = 0; i < n; ++i){ 
     p = new Array(m); 
     for(j = 0; j < m; p[j] = arguments[j][i], ++j); 
     t[i] = p; 
    } 
    return t; 
}, 

olarak Not halletmek.


Bu kodu, değişken atamalar olmadan "tamamen işlevsel" bir biçime dönüştürmek zor olmamalıdır. Mevcut kodunuz zaten gönderdiğim örnekte ilk iki fors'un işini tutmalı (fermuarın minimum uzunlukta kesilmesi ve listelerin birinin indeksleri boyunca yinelenmesi). Geriye kalanlar üçüncü için benzer bir şey yapıyor - iki listeden iki değer toplamak yerine i-inci değerini bir liste listesinden toplamak.

+0

Teşekkürler! Yine de, 'for' gibi yordamsal yineleyiciler kullanmadan uygulanıp uygulanamayacağı konusunda dolaşıyordum. – cbrandolino

+0

Kodunuz, zaten gönderdiğim örnekte ilk iki fors'un işini yapıyor olmalıdır (zip dosyasını minimum uzunlukta kesmek ve listelerin birinin dizinleri boyunca yinelemek). Tek yapmanız gereken üçüncünün görevidir - iki listeden iki değer toplamak yerine i-inci değerini bir liste listesinden toplamak. – hugomg

+0

Bu tür performansa duyarlı kütüphane işlevinde oldukça özyinelemeli kodlar tavsiye etmem. Ama sanırım bu durumda gerçekten bir sakıncası yok. – hugomg

İlgili konular