Мартин обнови решението на 22.10.2011 21:49 (преди около 13 години)
+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