Мартин обнови решението на 22.10.2011 21:49 (преди около 14 години)
+class Array
+ def to_hash()
+ hash = Hash[*self.flatten]
+ hash.default = 0
+ hash
+ end
+
+ def index_by()
+ values = []
+ self.each do |n|
+ values << (yield n)
+ end
+ values.zip(self).to_hash
+ end
+
+ def subarray_count(subarray)
+ subarray_count = 0
+ i = 0
+ while i < self.length
+ j = 0
+ while j < subarray.length and self.at(i) == subarray.at(j)
+ i+=1
+ j+=1
+ end
+ if j == subarray.length
+ subarray_count += 1
+ end
+ i -= j-1
+ end
+ subarray_count
+ end
+
+ def occurences_count()
+ tokens = []
+ result = []
+ self.each do |n|
+ if not tokens.include?(n)
+ tokens << n
+ end
+ end
+ tokens.each do |x|
+ occurences = 0
+ self.each do |y|
+ if x == y
+ occurences += 1
+ end
+ result << x
+ result << occurences
+ end
+ end
+ result.to_hash
+ end
+end
Много елитен код, бих пил чай с автора :)
Все пак моят subarray_count e по-грозен ;)
Георги, надявам се, че не се е*аваш с автора :)
Ето малко коментари и от мен:
- Както вече си разбрал,
Array#flattenне върши работа за#to_hash - В Ruby се идентира с 2 интервала; не с 4 интервала или табове с "ширина 2"
-
hash.default = 0е криптично и странно; странните и изненадващи неща не са препоръчителни за екипна работа; по-добреHash.new(0), защото е идиоматично за целта - Няма нужда от експлицитно указан
selfв случаите на викане на метод, напр.:self.each do ...е по-добре само катоeach do ... - Скобите в случаи като този:
values << (yield n)се поставят така:values << yield(n); в твоя вариант викаш "метода"yieldбез скоби, но си уградил целия израз в скоби, понеже интерпретаторът ти се е оплакал; в тези случаи най-добре е да си сложиш скобите около изивкването на функцията (в случая,yield) - Скоби около извикване/деклариране на метод без аргументи почти винаги се изпускат; напр.:
def to_hash()е по-четимо катоdef to_hash - Два вложени
while-a,i,j... Прекалено сложно :) Винаги ползвайeachзаEnumerableнеща, понеже, отново, е идиоматично; виж реализацията на този метод при Стефан, например -
if not somethingе по-четимо катоunless somethig; само че не ползвайunless, ако ти трябваelse-клон на логиката - Спокойно може да пишеш код от вида:
result << x << occurences; причината е, че методът<<връща обекта, над който е извикан и всъщност този израз е еквивалентен на:result.<<(x).<<(occurences)
Ама той започна :D
