1 ArrayedCollection : SequenceableCollection {
2 *newClear { arg indexedSize = 0;
5 // creates a new instance with indexedSize indexable slots.
6 // the slots are filled with nil, zero or something else
7 // appropriate to the type of indexable slots in the
11 // ArrayedCollections are vectors which have a
12 // fixed maximum capacity.
14 indexedSize { _BasicSize }
16 maxSize { _BasicMaxSize }
18 swap { arg i, j; var temp;
20 ^this.primitiveFailed;
25 ^this.primitiveFailed;
29 ^this.primitiveFailed;
33 ^this.primitiveFailed;
37 ^this.primitiveFailed;
39 put { arg index, item;
41 ^this.primitiveFailed;
43 clipPut { arg index, item;
45 ^this.primitiveFailed;
47 wrapPut { arg index, item;
49 ^this.primitiveFailed;
51 foldPut { arg index, item;
53 ^this.primitiveFailed;
57 ^this.primitiveFailed;
61 ^this.primitiveFailed;
66 ^this.primitiveFailed;
68 indexOfGreaterThan { arg val;
69 _ArrayIndexOfGreaterThan
70 ^super.indexOfGreaterThan(val)
75 while { i < this.size }
77 if (func.value(this[i], i)) {
85 replace { arg find, replace;
86 var index, out = [], array = this;
88 replace = replace.asArray;
90 (index = array.find(find)).notNil
92 out = out ++ array.keep(index) ++ replace;
93 array = array.drop(index + find.size);
98 // see counterparts to these in Object
105 slotPut { arg index, value;
106 ^this.put(index, value);
117 setSlots { arg array;
118 this.overWrite(array)
121 atModify { arg index, function; this.put(index, function.value(this.at(index), index)) }
122 atInc { arg index, inc=1; this.put(index, this.at(index)+inc); }
123 atDec { arg index, dec=1; this.put(index, this.at(index)-dec); }
128 copyRange { arg start, end;
129 // copies the fixed part of an object and the indexed slots
130 // from start to end.
132 ^this.primitiveFailed
134 copySeries { arg first, second, last;
135 // copies elements from first to last, stepping by (second-first)
136 // copySeries(3,5,11) copies elements 3,5,7,9,11
137 // if second is nil then the step is 1.
138 // copySeries(3,nil,11) copies elements 3,4,5,6,7,8,9,10,11
140 ^this.primitiveFailed
142 putSeries { arg first, second, last, value;
143 // puts value into array at indices defined by the series. see copySeries.
145 ^this.primitiveFailed
149 // add item to end of array.
150 // if the capacity is exceeded, this returns a new
151 // ArrayedCollection.
153 ^this.primitiveFailed;
155 addAll { arg aCollection;
159 aCollection.asCollection.do({ arg item; array = array.add(item) }) ;
162 putEach { arg keys, values;
164 ^super.putEach(keys, values)
166 extend { arg size, item;
168 ^this.primitiveFailed
170 insert { arg index, item;
171 // add item at specified index.
172 // if the capacity is exceeded, this returns a new
173 // ArrayedCollection.
175 ^this.primitiveFailed;
177 addFirst { arg item; ^this.insert(0, item) }
178 addIfNotNil { arg item; if(item.notNil,{ ^this.add(item) }) }
180 // remove and return last item in array
185 // concatenate two arrays of the same type
186 // this primitive will handle all array element types
188 // primitive fails if arrays are different types
191 overWrite { arg aCollection, pos=0;
194 ^this.primitiveFailed
195 //array = this.growClear(pos + aCollection.size - this.size);
196 //grow = pos + aCollection.size - this.size;
197 //if (grow > 0, { array = this ++ this.class.newClear(grow); },{ array = this });
198 //aCollection.do({ arg item, i; array.put(pos + i, item); });
201 grow { arg sizeIncrease;
202 // returns an array of sufficient capacity.
203 // may return same object if it still has enough space or if sizeIncrease <= 0.
205 ^this.primitiveFailed
207 growClear { arg sizeIncrease;
208 // returns an array of sufficient capacity.
209 // may return same object if it still has enough space or if sizeIncrease <= 0.
212 ^this.primitiveFailed
214 seriesFill { arg start, step;
215 this.size.do({ arg i;
217 start = start + step;
223 ^this.primitiveFailed
224 /* replaced by primitive
227 while ({ i < size }, {
234 // special byte codes inserted by compiler for this method
236 while ({ i < this.size }, {
237 function.value(this.at(i), i);
241 reverseDo { arg function;
242 // special byte codes inserted by compiler for this method
246 function.value(this.at(i), j);
254 var size1 = res.size - 1;
255 var halfsize = res.size div: 2;
257 res.swap(i, size1 - i);
264 ^this.primitiveFailed
265 // var r, sum = 0.0, index;
267 // this.detect({ arg weight, i;
268 // sum = sum + weight;
278 ^(this * this.sum.reciprocal)
280 normalize { arg min=0.0, max=1.0;
281 var minItem = this.minItem;
282 var maxItem = this.maxItem;
283 ^this.collect { |el| el.linlin(minItem, maxItem, min, max) };
287 // draw the waveform down the page as asterisks
288 var lo = this.minItem;
289 var hi = this.maxItem;
290 var scale = 80 / (hi - lo);
292 var pt = ((this[i] - lo) * scale).asInteger;
293 pt.do({ " ".post; });
299 if(this.size < 2) { ^this.copy };
300 ^this[(0 .. this.size div: 2 - 1).stutter + [0, this.size + 1 div: 2]]
303 performInPlace { arg selector, from, to, argList;
304 ^this.overWrite(this.copyRange(from, to).performList(selector, argList), from)
307 clipExtend { arg length;
308 ^this.extend(length, this.last)
311 // concepts borrowed from J programming language
313 // rank is the number of dimensions in a multidimensional array.
314 // see also Object-rank
315 // this assumes every element has the same rank
316 ^ 1 + this.first.rank
319 // this assumes every element has the same shape
320 ^[this.size] ++ this[0].shape
322 reshape { arg ... shape;
323 var size = shape.product;
324 var result = this.flat.wrapExtend(size);
325 shape[1..].reverseDo {|n| result = result.clump(n) };
328 deepCollect { arg depth = 1, function;
330 ^function.value(this, 0)
333 ^this.collect {|item| item.deepCollect(depth, function) }
335 reshapeLike { arg another, indexing=\wrapAt;
337 var flat = this.flat;
338 ^another.deepCollect(0x7FFFFFFF) {
339 var item = flat.perform(indexing, index);
345 unbubble { arg depth=0, levels=1;
347 // converts a size 1 array to the item.
348 if (this.size > 1) { ^this };
349 if (levels <= 1) { ^this[0] }
350 ^this[0].unbubble(depth, levels-1)
352 ^this.collect {|item| item.unbubble(depth-1) }
354 bubble { arg depth=0, levels=1;
356 if (levels <= 1) { ^[this] }
357 ^[this.bubble(depth,levels-1)]
359 ^this.collect {|item| item.bubble(depth-1, levels) }
363 slice { arg ... cuts;
364 var firstCut, index, list;
365 if (cuts.size == 0) { ^this.copy };
368 if (firstCut.isNil) { list = this.copy } { list = this[firstCut.asArray] };
369 if (cuts.size == 1) {
373 ^list.collect {|item| item.slice(*cuts) }.unbubble
376 *iota { arg ... sizes;
377 ^(0..sizes.product-1).reshape(*sizes)
379 *fill2D { arg rows, cols, function;
380 var array = this.new(rows);
382 var array2 = this.new(cols);
384 array2 = array2.add(function.(row, col))
386 array = array.add(array2);
390 *fill3D { arg planes, rows, cols, function;
391 var array = this.new(planes);
393 var array2 = this.new(rows);
395 var array3 = this.new(cols);
397 array3 = array3.add(function.(plane, row, col))
399 array2 = array2.add(array3);
401 array = array.add(array2);
405 *fillND { arg dimensions, function, args=[]; // args are private
406 var n = dimensions.first;
407 var array = this.new(n);
408 var argIndex = args.size;
410 if(dimensions.size <= 1) {
411 n.do { |i| array.add(function.valueArray(args.put(argIndex, i))) };
413 dimensions = dimensions.drop(1);
415 var array2 = this.fillND(dimensions, function, args.put(argIndex, i));
416 array = array.add(array2);
423 // random distribution table
425 asRandomTable { arg size;
427 if(size.isNil) { size = this.size } { a = a.resamp1(size) };
428 a = a.integrate; // incrementally integrate
429 a = a.normalize(0, size-1); // normalize and scale by max index
430 b = Array.fill(size, { arg i; a.indexInBetween(i) }); // flip array
431 b = b / size // rescale to 0..1
436 ^this.blendAt((this.size - 1).asFloat.rand)
439 // osc bundle support
443 ^this.primitiveFailed
447 ^([nil] ++ this).prBundleSize;
450 var size=0, res, clumps, count=0, bundleSizes;
451 bundleSizes = this.collect {|item| [item].bundleSize };
452 bundleSizes.do { |a, i|
454 if(size >= 8192) { clumps = clumps.add(count); count = 0; size = a };
457 ^this.clumps(clumps);
462 ^this.primitiveFailed
464 includes { |item| ^this.indexOf(item).notNil }
467 RawArray : ArrayedCollection {
468 // species { ^this.class }
469 archiveAsCompileString { ^true }
470 archiveAsObject { ^true }
474 readFromStream { |stream, method|
477 this.put(i, stream.perform(method));
480 this.shouldNotImplement(thisMethod);
485 ^this.as(Array).powerset
489 Int8Array[int8] : RawArray {
492 ^this.primitiveFailed
495 readFromStream { |stream|
496 super.readFromStream(stream, \getInt8);
500 Int16Array[int16] : RawArray {
501 readFromStream { |stream|
502 super.readFromStream(stream, \getInt16);
506 Int32Array[int32] : RawArray {
507 readFromStream { |stream|
508 super.readFromStream(stream, \getInt32);
512 FloatArray[float] : RawArray {
513 readFromStream { |stream|
514 super.readFromStream(stream, \getFloat);
518 DoubleArray[double] : RawArray {
519 readFromStream { |stream|
520 super.readFromStream(stream, \getDouble);
524 // readFromStream not implemented yet
525 SymbolArray[symbol] : RawArray {