From 21d553ba02f7a212b85d0418ff7abc436f7dc675 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 21 Apr 2013 17:27:02 -0400 Subject: [PATCH] working on List class --- core/src/processing/data/IntList.java | 397 ++++++++++++++++++++++---- core/todo.txt | 14 + 2 files changed, 360 insertions(+), 51 deletions(-) diff --git a/core/src/processing/data/IntList.java b/core/src/processing/data/IntList.java index fefb8b762..c72b8a39a 100644 --- a/core/src/processing/data/IntList.java +++ b/core/src/processing/data/IntList.java @@ -1,14 +1,17 @@ package processing.data; +import java.util.Arrays; +import java.util.Random; + import processing.core.PApplet; /** - * Helper class for a list of floats. + * Helper class for a list of ints. */ public class IntList { - int count; - int[] data; + protected int count; + protected int[] data; public IntList() { @@ -23,6 +26,19 @@ public class IntList { } + /** + * Improve efficiency by removing allocated but unused entries from the + * internal array used to store the data. Set to private, though it could + * be useful to have this public if lists are frequently making drastic + * size changes (from very large to very small). + */ + private void crop() { + if (count != data.length) { + data = PApplet.subset(data, 0, count); + } + } + + /** * Get the length of the list. */ @@ -31,6 +47,28 @@ public class IntList { } + public void resize(int length) { + if (length > count) { +// // make sure the entries in data[] that are past 'count' are set to zero +// for (int i = count; i < data.length; i++) { +// data[i] = 0; +// } +// data = PApplet.expand(data, length); + int[] temp = new int[length]; + System.arraycopy(data, 0, temp, 0, count); + } + count = length; + } + + + /** + * Remove all entries from the list. + */ + public void clear() { + count = 0; + } + + /** * Get an entry at a particular index. */ @@ -40,27 +78,44 @@ public class IntList { /** - * Set the entry at a particular index. + * Set the entry at a particular index. If the index is past the length of + * the list, it'll expand the list to accommodate, and fill the intermediate + * entries with 0s. */ public void set(int index, int what) { if (index >= count) { data = PApplet.expand(data, index+1); + for (int i = count; i < index; i++) { + data[i] = 0; + } + count = index+1; } data[index] = what; } - public int removeIndex(int index) { - int bye = data[index]; - PApplet.println(data); - int[] outgoing = new int[count - 1]; - System.arraycopy(data, 0, outgoing, 0, index); + /** remove an element from the specified index */ + public void remove(int index) { +// int[] outgoing = new int[count - 1]; +// System.arraycopy(data, 0, outgoing, 0, index); +// count--; +// System.arraycopy(data, index + 1, outgoing, 0, count - index); +// data = outgoing; + for (int i = index; i < count; i++) { + data[i] = data[i+1]; + } count--; - System.arraycopy(data, index + 1, outgoing, 0, count - index); - data = outgoing; - PApplet.println(data); - PApplet.println(); - return bye; + } + + + /** remove the first instance of a particular value */ + public boolean removeValue(int value) { + int index = index(value); + if (index != -1) { + remove(index); + return true; + } + return false; } @@ -75,6 +130,104 @@ public class IntList { } +// public void insert(int index, int value) { +// if (index+1 > count) { +// if (index+1 < data.length) { +// } +// } +// if (index >= data.length) { +// data = PApplet.expand(data, index+1); +// data[index] = value; +// count = index+1; +// +// } else if (count == data.length) { +// if (index >= count) { +// //int[] temp = new int[count << 1]; +// System.arraycopy(data, 0, temp, 0, index); +// temp[index] = value; +// System.arraycopy(data, index, temp, index+1, count - index); +// data = temp; +// +// } else { +// // data[] has room to grow +// // for() loop believed to be faster than System.arraycopy over itself +// for (int i = count; i > index; --i) { +// data[i] = data[i-1]; +// } +// data[index] = value; +// count++; +// } +// } + + + // same as splice + public void insert(int index, int[] values) { + if (index < 0 || index >= count) { + throw new IllegalArgumentException("Index " + index + " is outside this list's size"); + } + + int[] temp = new int[count + values.length]; + + // Copy the old values, but not more than already exist + System.arraycopy(data, 0, temp, 0, Math.min(count, index)); + + // Copy the new values into the proper place + System.arraycopy(values, 0, temp, index, values.length); + +// if (index < count) { + // The index was inside count, so it's a true splice/insert + System.arraycopy(data, index, temp, index+values.length, count - index); + count = count + values.length; +// } else { +// // The index was past 'count', so the new count is weirder +// count = index + values.length; +// } + data = temp; + + // below are aborted attempts at more optimized versions of the code + // that are harder to read and debug... + +// if (index + values.length >= count) { +// // We're past the current 'count', check to see if we're still allocated +// // index 9, data.length = 10, values.length = 1 +// if (index + values.length < data.length) { +// // There's still room for these entries, even though it's past 'count'. +// // First clear out the entries leading up to it, however. +// for (int i = count; i < index; i++) { +// data[i] = 0; +// } +// data[index] = +// } +// if (index >= data.length) { +// int length = index + values.length; +// int[] temp = new int[length]; +// System.arraycopy(data, 0, temp, 0, count); +// System.arraycopy(values, 0, temp, index, values.length); +// data = temp; +// count = data.length; +// } else { +// +// } +// +// } else if (count == data.length) { +// int[] temp = new int[count << 1]; +// System.arraycopy(data, 0, temp, 0, index); +// temp[index] = value; +// System.arraycopy(data, index, temp, index+1, count - index); +// data = temp; +// +// } else { +// // data[] has room to grow +// // for() loop believed to be faster than System.arraycopy over itself +// for (int i = count; i > index; --i) { +// data[i] = data[i-1]; +// } +// data[index] = value; +// count++; +// } + } + + public int index(int what) { /* if (indexCache != null) { @@ -104,13 +257,13 @@ public class IntList { // } - public boolean contains(int what) { + public boolean contains(int value) { // if (indexCache == null) { // cacheIndices(); // } // return index(what) != -1; for (int i = 0; i < count; i++) { - if (data[i] == what) { + if (data[i] == value) { return true; } } @@ -118,55 +271,197 @@ public class IntList { } + public void inc(int index) { + data[index]++; + } + + + public void inc(int index, int amount) { + data[index] += amount; + } + + + public void dec(int index) { + data[index]--; + } + + + public void dec(int index, int amount) { + data[index] -= amount; + } + + + public void mul(int index, int amount) { + data[index] *= amount; + } + + + public void div(int index, int amount) { + data[index] /= amount; + } + + +// public void inc(int amt) { +// for (int i = 0; i < count; i++) { +// data[i] += amt; +// } +// } +// +// +// public void dec(int amt) { +// for (int i = 0; i < count; i++) { +// data[i] -= amt; +// } +// } +// +// +// public void mul(int amt) { +// for (int i = 0; i < count; i++) { +// data[i] *= amt; +// } +// } +// +// +// public void div(int amt) { +// for (int i = 0; i < count; i++) { +// data[i] /= amt; +// } +// } + + + public int min() { + if (count == 0) { + throw new ArrayIndexOutOfBoundsException("Cannot use min() on IntList of length 0."); + } + int outgoing = data[0]; + for (int i = 1; i < data.length; i++) { + if (data[i] < outgoing) outgoing = data[i]; + } + return outgoing; + } + + + public int max() { + if (count == 0) { + throw new ArrayIndexOutOfBoundsException("Cannot use max() on IntList of length 0."); + } + int outgoing = data[0]; + for (int i = 1; i < data.length; i++) { + if (data[i] > outgoing) outgoing = data[i]; + } + return outgoing; + } + + + /** Sorts the array in place. To get a sorted copy, use list.copy().sort(). */ + public void sort() { + Arrays.sort(data, 0, count); + } + + + /** reverse sort, orders values from highest to lowest */ + public void rsort() { + new Sort() { + @Override + public int size() { + return count; + } + + @Override + public float compare(int a, int b) { + return data[a] - data[b]; + } + + @Override + public void swap(int a, int b) { + int temp = a; + a = b; + b = temp; + } + }.run(); + } + + + // use insert() +// public void splice(int index, int value) { +// } + + + public void subset(int start) { + subset(start, count - start); + } + + + public void subset(int start, int num) { + for (int i = 0; i < num; i++) { + data[i] = data[i+start]; + } + count = num; + } + + + public void concat(int[] values) { + + } + + + public void concat(IntList list) { + + } + + + public void reverse() { + + } + + + // splice, slice, subset, concat, reverse + + // trim, join for String versions + /** - * Remove all entries from the list. + * Randomize the order of the list elements. Note that this does not + * obey the randomSeed() function in PApplet. */ - public void clear() { - count = 0; + public void shuffle() { + Random r = new Random(); + int num = count; + while (num > 1) { + int value = r.nextInt(num); + num--; + int temp = data[num]; + data[num] = data[value]; + data[value] = temp; + } } /** - * Improve efficiency by removing allocated but unused entries from the - * internal array used to store the data. + * Randomize the list order using the random() function from the specified + * sketch, allowing shuffle() to use its current randomSeed() setting. */ - public void crop() { - if (count != data.length) { - data = PApplet.subset(data, 0, count); + public void shuffle(PApplet sketch) { + int num = count; + while (num > 1) { + int value = (int) sketch.random(num); + num--; + int temp = data[num]; + data[num] = data[value]; + data[value] = temp; } } - public void add(int amt) { - for (int i = 0; i < count; i++) { - data[i] += amt; - } - } - - - public void sub(int amt) { - for (int i = 0; i < count; i++) { - data[i] -= amt; - } - } - - - public void mul(int amt) { - for (int i = 0; i < count; i++) { - data[i] *= amt; - } - } - - - public void div(int amt) { - for (int i = 0; i < count; i++) { - data[i] /= amt; - } + public IntList copy() { + IntList outgoing = new IntList(data); + outgoing.count = count; + return outgoing; } /** * Returns the actual array being used to store the data. + * Suitable for iterating, but do not modify. */ public int[] values() { crop(); @@ -178,7 +473,7 @@ public class IntList { * Create a new array with a copy of all the values. * @return an array sized by the length of the list with each of the values. */ - public int[] toArray() { + public int[] getArray() { int[] outgoing = new int[count]; System.arraycopy(data, 0, outgoing, 0, count); return outgoing; @@ -189,7 +484,7 @@ public class IntList { * Copy as many values as possible into the specified array. * @param array */ - public void toArray(int[] array) { + public void getArray(int[] array) { System.arraycopy(data, 0, array, 0, Math.min(count, array.length)); } } \ No newline at end of file diff --git a/core/todo.txt b/core/todo.txt index fb60a11ec..7530345bc 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -17,6 +17,13 @@ _ https://github.com/processing/processing/issues/1709 _ tint() with JAVA2D does not automatically refresh (with possible fix) _ https://github.com/processing/processing/issues/1730 +_ include Instant and Interval? + +_ naming for descending sort +_ rsort(), sortReverse(), sortKeysReverse, +_ sortDescend, sortDescending, sortKeysDescending, +_ sortHighLow, sortHigh, sortHighest, sortDown + hash/dict/etc _ need to sort out the final version of these and their names _ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey() @@ -26,6 +33,13 @@ _ contains() as default, then containsValue() as the alternate _ instead of containsKey() and containsValue() _ add() to add things to lists, inc/dec for the math _ inc/dec/sum is used less, after all +_ will also need an iterator for the Dict class ala Map.Entry + +List: remove(), append(), index(), etc all use values + removeIndex(index) is the other + otherwise remove() would be the only one that dealt with indices + Dict will use remove(key), so using remove(index) as default + and removeValue(value) is probably used less table _ table writing twice when .csv is added