Class: HArray
Overview
:title: HArray
HArray is an implemenation of the Array class using only Hashes. Regular Arrays are never used except once to delegate the #pack method, and for *args parameters (since there is no way around those is some cases). HArray is for all practical purposes 100% compatible with Array.
HArray is slower then the built in Array class, but not as slow as one might expect, since a Hash in general is faster than an Array. It might be interesting to see how this would perform if it were written in c. Not all that useful, but an interesting example.
AUTHOR(s)
Class Method Summary
collapse
Instance Method Summary
collapse
#restore_snapshot, #take_snapshot
Constructor Details
#initialize(i = 0, e = nil) ⇒ HArray
Returns a new instance of HArray.
54
55
56
57
58
|
# File 'lib/mega/harray.rb', line 54
def initialize(i=0,e=nil)
if i > 0
i.times { self.set(self.length,e) }
end
end
|
Class Method Details
.[](*args) ⇒ Object
42
43
44
45
46
|
# File 'lib/mega/harray.rb', line 42
def HArray.[](*args)
nha = HArray.new
args.each { |a| nha.set(nha.length,a) }
nha
end
|
.new_h(hsh) ⇒ Object
48
49
50
51
52
|
# File 'lib/mega/harray.rb', line 48
def HArray.new_h(hsh)
nha=HArray.new
nha.replace(hsh)
end
|
Instance Method Details
60
61
62
63
64
65
66
67
68
|
# File 'lib/mega/harray.rb', line 60
def &(ha)
nha=HArray.new
(0..self.length-1).each do |i|
if ha.has_value?(self.fetch(i)) and !nha.has_value?(self.fetch(i))
nha.set(nha.length,self.fetch(i))
end
end
nha
end
|
70
71
72
73
74
75
76
77
78
|
# File 'lib/mega/harray.rb', line 70
def *(j)
if j.kind_of?(String)
return self.join(j)
else
nha = HArray.new
j.times { (0...self.length).each { |i| nha.set(nha.length,self.fetch(i)) } }
return nha
end
end
|
80
81
82
83
84
|
# File 'lib/mega/harray.rb', line 80
def +(ha)
nha = self.dup
(0..ha.length-1).each { |i| nha.set(nha.length,ha.fetch(i)) }
nha
end
|
86
87
88
89
90
91
|
# File 'lib/mega/harray.rb', line 86
def -(ha)
nha = HArray.new
self.each { |v| nha << v if !ha.has_value?(v) }
nha
end
|
93
94
95
96
|
# File 'lib/mega/harray.rb', line 93
def <<(e)
self.set(self.length,e)
self
end
|
98
99
100
101
102
103
104
|
# File 'lib/mega/harray.rb', line 98
def <=>(ha)
(0..self.length-1).each do |i|
ieq = (self.fetch(i) <=> ha.fetch(i))
return ieq if ieq != 0
end
self.length <=> ha.length
end
|
106
107
108
|
# File 'lib/mega/harray.rb', line 106
def ===(ha)
self.==(ha)
end
|
#[](i, l = nil) ⇒ Object
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/mega/harray.rb', line 113
def [](i,l=nil)
if l
i = i...i+l
elsif ! i.kind_of?(Range)
return self.at(i)
end
nha = HArray.new
i.each { |j| nha.set(nha.length,get(j)) if has_key?(j) }
nha
end
|
#[]=(i, b, c = nil) ⇒ Object
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# File 'lib/mega/harray.rb', line 125
def []=(i,b,c=nil)
if c
rng = (Integer(i)..Integer(i+b))
b = c
elsif i.kind_of? Range
rng = i
else
self.set(Integer(i),b)
return b
end
if b == nil
rng.each { |i| qdelete(i) }
self.reindex!
elsif b.kind_of?(Array) or b.kind_of?(HArray)
j = 0
rng.each { |i| self[i] = b[j]; j+=1 }
else
rng.each { |i| qdelete(i) }
self[rng.fist] = b
self.reindex!
end
end
|
154
155
156
157
|
# File 'lib/mega/harray.rb', line 154
def assoc(k)
(0...self.length).each { |i| return self.fetch(i) if self.fetch(i)[0] == k }
return nil
end
|
159
160
161
162
163
164
|
# File 'lib/mega/harray.rb', line 159
def at(i)
i = self.length + i if i <= -1
get(i)
end
|
168
169
170
171
172
|
# File 'lib/mega/harray.rb', line 168
def collect
nha = HArray.new
(0...self.length).each { |i| nha << yield(self.fetch(i)) }
nha
end
|
#collect! ⇒ Object
Also known as:
map!
174
175
176
177
178
|
# File 'lib/mega/harray.rb', line 174
def collect!
nha = HArray.new
(0...self.length).each { |i| nha << yield(self.fetch(i)) }
self.replace(nha)
end
|
180
181
182
183
184
185
186
187
188
189
|
# File 'lib/mega/harray.rb', line 180
def compact
nha, j = HArray.new, 0
(0..self.length-1).each do |i|
if self.fetch(i) != nil
nha.set(j,self.fetch(i))
j+=1
end
end
nha
end
|
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/mega/harray.rb', line 191
def compact!
if self.has_value?(nil)
nha, j = HArray.new, 0
(0..self.length-1).each do |i|
if self.fetch(i) != nil
nha.set(j,self.fetch(i))
j+=1
end
end
return self.replace(nha)
else
return nil
end
end
|
#concat(ha) ⇒ Object
206
207
208
209
|
# File 'lib/mega/harray.rb', line 206
def concat(ha)
(0...ha.length).each { |i| self.set(self.length,ha.fetch(i)) }
self
end
|
#count(e = nil) ⇒ Object
211
212
213
214
215
216
217
218
219
220
221
|
# File 'lib/mega/harray.rb', line 211
def count(e=nil)
if block_given?
cnt = 0
(0...self.length).each { |i| cnt += 1 if yield(self.fetch(i)) }
return cnt
else
cnt = 0
(0...self.length).each { |i| cnt += 1 if self.fetch(i) == e }
return cnt
end
end
|
#delete(e) ⇒ Object
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/mega/harray.rb', line 226
def delete(e)
if has_value?(e)
qdelete_if { |i,v| v == e }
reindex!
return e
else
return yield if block_given?
return nil
end
end
|
#delete_at(i) ⇒ Object
237
238
239
240
241
242
243
244
245
246
|
# File 'lib/mega/harray.rb', line 237
def delete_at(i)
if self.has_key?(i)
e = self.fetch(i)
qdelete(i)
reindex!
return e
else
return nil
end
end
|
#delete_if ⇒ Object
251
252
253
254
|
# File 'lib/mega/harray.rb', line 251
def delete_if
qdelete_if { |i,v| yield(v) }
reindex!
end
|
256
257
258
|
# File 'lib/mega/harray.rb', line 256
def each
(0...self.length).each { |i| yield(self.fetch(i)) }
end
|
#each_index ⇒ Object
260
261
262
|
# File 'lib/mega/harray.rb', line 260
def each_index
(0...self.length).each { |i| yield(i) }
end
|
#eql?(ha) ⇒ Boolean
266
267
268
269
270
|
# File 'lib/mega/harray.rb', line 266
def eql?(ha)
return false if self.length != ha.length
return true if (0...self.length).all? { |i| self.fetch(i).eql?(ha.fetch(i)) }
return false
end
|
#fill(f, s = nil, l = nil) ⇒ Object
272
273
274
275
276
277
278
279
280
281
282
|
# File 'lib/mega/harray.rb', line 272
def fill(f,s=nil,l=nil)
if s.kind_of?(Range)
r = s
else
s = 0 if !s
l = self.length - s if !l
r = s...(s+l)
end
r.each{ |i| self.set(i,f) }
self
end
|
284
285
286
287
|
# File 'lib/mega/harray.rb', line 284
def first
return nil if self.empty?
self.fetch(0)
end
|
289
290
291
292
293
294
295
296
297
298
299
300
|
# File 'lib/mega/harray.rb', line 289
def flatten
nha = HArray.new
(0...self.length).each do |i|
sfi = self.fetch(i)
if sfi.kind_of?(HArray) or sfi.kind_of?(Array)
nha.concat(sfi.flatten)
else
nha.set(nha.length,sfi)
end
end
nha
end
|
302
303
304
305
|
# File 'lib/mega/harray.rb', line 302
def flatten!
return nil if !self.any? { |e| e.kind_of?(HArray) or e.kind_of?(Array) }
self.replace(self.flatten)
end
|
#include?(v) ⇒ Boolean
307
308
309
|
# File 'lib/mega/harray.rb', line 307
def include?(v)
self.has_value?(v)
end
|
#join(sep = '') ⇒ Object
313
314
315
316
317
|
# File 'lib/mega/harray.rb', line 313
def join(sep='')
s = ''
(0...self.length).each { |i| s << "#{self.fetch(i)}#{sep}" }
return s.chomp(sep)
end
|
319
320
321
|
# File 'lib/mega/harray.rb', line 319
def last
self[self.length-1]
end
|
327
328
329
330
331
|
# File 'lib/mega/harray.rb', line 327
def nitems
cnt = 0
(0...self.length).each { |i| cnt += 1 if self.fetch(i) != nil }
cnt
end
|
#pack(*args) ⇒ Object
333
334
335
|
# File 'lib/mega/harray.rb', line 333
def pack(*args)
self.to_a.pack(*args)
end
|
337
338
339
|
# File 'lib/mega/harray.rb', line 337
def pop
self.delete_at(self.length-1)
end
|
341
342
343
|
# File 'lib/mega/harray.rb', line 341
def push(*e)
self.concat(e)
end
|
#qsort(ha, l, r) ⇒ Object
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
|
# File 'lib/mega/harray.rb', line 440
def qsort(ha, l, r)
l_hold = l
r_hold = r
pivot = ha[l]
while l < r
r -= 1 while (ha[r] <=> pivot) >= 0 and l < r
if l != r
ha[l] = ha[r]
l += 1
end
l += 1 while (ha[l] <=> pivot) <= 0 and l < r
if l != r
ha[r] = ha[l]
r -= 1
end
end
ha[l] = pivot
pivot = l
l = l_hold
r = r_hold
qsort(ha,l,pivot-1) if l < pivot
qsort(ha,pivot+1,r) if r > pivot
ha
end
|
#rassoc(k) ⇒ Object
345
346
347
348
|
# File 'lib/mega/harray.rb', line 345
def rassoc(k)
(0...self.length).each { |i| return self.fetch(i) if self.fetch(i)[1] == k }
return nil
end
|
350
351
352
353
354
355
356
357
358
359
360
361
|
# File 'lib/mega/harray.rb', line 350
def reindex
nha, j, k, tl = HArray.new, 0, 0, self.length
while k < tl
if self.has_key?(j)
nha.set(k,self.fetch(j))
j+=1; k+=1
else
j+=1
end
end
nha
end
|
363
364
365
|
# File 'lib/mega/harray.rb', line 363
def reindex!
self.replace(self.reindex)
end
|
367
368
369
370
371
372
|
# File 'lib/mega/harray.rb', line 367
def reject!
chg=nil
qdelete_if { |i,v| r=yield(v); chg=true if r; r }
return nil if !chg
reindex!
end
|
def replace(ha)
if ha.length < self.length
(ha.length..self.length-1).each { |i| self.delete(i) }
(0..ha.length-1).each { |i| self.set(i,ha[i]) }
end
end
381
382
383
384
385
|
# File 'lib/mega/harray.rb', line 381
def reverse
nha = HArray.new
(0...self.length).each { |i| nha.set(self.length-1-i,self.fetch(i)) }
nha
end
|
387
388
389
390
391
392
393
394
395
|
# File 'lib/mega/harray.rb', line 387
def reverse!
(0...self.length/2).each do |i|
ri = self.length-1-i
tmp = self.fetch(ri)
self.set(ri,self.fetch(i))
self.set(i,tmp)
end
self
end
|
#reverse_each ⇒ Object
397
398
399
400
401
402
403
|
# File 'lib/mega/harray.rb', line 397
def reverse_each
i = self.length - 1
while i >= 0
yield(self.fetch(i))
i -= 1
end
end
|
#rindex(e) ⇒ Object
405
406
407
408
409
410
411
412
|
# File 'lib/mega/harray.rb', line 405
def rindex(e)
i = self.length - 1
while i >= 0
return i if self.fetch(i) == e
i -= 1
end
return nil
end
|
124
|
# File 'lib/mega/harray.rb', line 124
alias set []=
|
414
415
416
417
418
419
420
|
# File 'lib/mega/harray.rb', line 414
def shift
e1 = self[0]
tl = self.length - 1
(1..tl).each { |i| self.set(i-1,self.fetch(i)) }
self.delete_at(tl)
e1
end
|
#slice(*args) ⇒ Object
424
425
426
|
# File 'lib/mega/harray.rb', line 424
def slice(*args)
self[*args]
end
|
#slice!(*args) ⇒ Object
428
429
430
431
432
|
# File 'lib/mega/harray.rb', line 428
def slice!(*args)
result = self[*args]
self[*args] = nil
result
end
|
434
435
436
437
438
|
# File 'lib/mega/harray.rb', line 434
def sort
raise "HArray does not currently support sorting with blocks" if block_given?
nha = self.dup
qsort(nha,0,nha.length-1)
end
|
465
466
467
468
|
# File 'lib/mega/harray.rb', line 465
def sort!
raise "HArray does not currently support sorting with blocks" if block_given?
qsort(self,0,self.length-1)
end
|
470
471
472
473
474
|
# File 'lib/mega/harray.rb', line 470
def to_a
a = []
(0..self.length-1).each { |i| a << self.fetch(i) }
a
end
|
476
477
478
|
# File 'lib/mega/harray.rb', line 476
def to_ary
self
end
|
480
481
482
483
484
|
# File 'lib/mega/harray.rb', line 480
def to_h
h = Hash.new
self.each { |k,v| h[k] = v }
h
end
|
486
487
488
|
# File 'lib/mega/harray.rb', line 486
def to_s
self.join
end
|
490
491
492
493
494
495
496
|
# File 'lib/mega/harray.rb', line 490
def uniq
nha = HArray.new
(0..self.length-1).each do |i|
nha[nha.length] = self[i] if !nha.has_value?(self[i])
end
nha
end
|
498
499
500
501
502
503
504
505
506
507
|
# File 'lib/mega/harray.rb', line 498
def uniq!
j = 0
(1..self.length-1).each do |i|
if !self[0..j].has_value?(self[i])
self[j+1] = self[i]
j+=1
end
end
(j+1..self.length-1).each { |i| qdelete(i) }
end
|
#unshift(e) ⇒ Object
509
510
511
512
513
514
515
516
517
518
|
# File 'lib/mega/harray.rb', line 509
def unshift(e)
i = self.length - 1
while i >= 0
self.set(i+1,self.fetch(i))
return i if self.fetch(i) == e
i -= 1
end
self.set(0,e)
self
end
|
#values_at(*ix) ⇒ Object
520
521
522
523
524
|
# File 'lib/mega/harray.rb', line 520
def values_at(*ix)
nha = HArray.new
ix.each {|i| nha[nha.length] = self.at(i)}
nha
end
|
148
149
150
151
152
|
# File 'lib/mega/harray.rb', line 148
def |(ha)
nha = self.dup
ha.each { |v| nha << v if !nha.has_value?(v) }
nha
end
|