further normalization of the data API

This commit is contained in:
Ben Fry
2013-04-28 13:20:56 -04:00
parent fe8690844f
commit 4fd831fb89
6 changed files with 1134 additions and 131 deletions
+469 -112
View File
@@ -1,5 +1,9 @@
package processing.data;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
import processing.core.PApplet;
@@ -20,30 +24,177 @@ public class FloatList {
}
public FloatList(String[] list) {
this(PApplet.parseFloat(list));
/**
* 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.
*/
public int size() {
return count;
}
public void resize(int length) {
if (length > data.length) {
float[] temp = new float[length];
System.arraycopy(data, 0, temp, 0, count);
data = temp;
} else if (length > count) {
Arrays.fill(data, count, length, 0);
}
count = length;
}
/**
* Remove all entries from the list.
*/
public void clear() {
count = 0;
}
/**
* Get an entry at a particular index.
*/
public float get(int index) {
return data[index];
}
public void set(int index, int what) {
/**
* 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, float 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 void append(int value) {
/** 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--;
}
/** Remove the first instance of a particular value */
public boolean removeValue(float value) {
if (Float.isNaN(value)) {
for (int i = 0; i < count; i++) {
if (Float.isNaN(data[i])) {
remove(i);
return true;
}
}
} else {
int index = index(value);
if (index != -1) {
remove(index);
return true;
}
}
return false;
}
/** Remove all instances of a particular value */
public boolean removeValues(float value) {
int ii = 0;
if (Float.isNaN(value)) {
for (int i = 0; i < count; i++) {
if (!Float.isNaN(data[i])) {
data[ii++] = data[i];
}
}
} else {
for (int i = 0; i < count; i++) {
if (data[i] != value) {
data[ii++] = data[i];
}
}
}
if (count == ii) {
return false;
}
count = ii;
return true;
}
/** Replace the first instance of a particular value */
public boolean replaceValue(float value, float newValue) {
if (Float.isNaN(value)) {
for (int i = 0; i < count; i++) {
if (Float.isNaN(data[i])) {
data[i] = newValue;
return true;
}
}
} else {
int index = index(value);
if (index != -1) {
data[index] = newValue;
return true;
}
}
return false;
}
/** Replace all instances of a particular value */
public boolean replaceValues(float value, float newValue) {
boolean changed = false;
if (Float.isNaN(value)) {
for (int i = 0; i < count; i++) {
if (Float.isNaN(data[i])) {
data[i] = newValue;
changed = true;
}
}
} else {
for (int i = 0; i < count; i++) {
if (data[i] == value) {
data[i] = newValue;
changed = true;
}
}
}
return changed;
}
/** Add a new entry to the list. */
public void append(float value) {
if (count == data.length) {
data = PApplet.expand(data);
}
@@ -51,12 +202,205 @@ public class FloatList {
}
public void clear() {
count = 0;
public void append(float[] values) {
for (float v : values) {
append(v);
}
}
public float calcMin() {
public void append(FloatList list) {
for (float v : list.values()) { // will concat the list...
append(v);
}
}
// 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) {
throw new IllegalArgumentException("insert() index cannot be negative: it was " + index);
}
if (index >= values.length) {
throw new IllegalArgumentException("insert() index " + index + " is past the end of this list");
}
float[] temp = new float[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;
}
public void insert(int index, IntList list) {
insert(index, list.values());
}
// 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++;
// }
/** Return the first index of a particular value. */
public int index(float what) {
/*
if (indexCache != null) {
try {
return indexCache.get(what);
} catch (Exception e) { // not there
return -1;
}
}
*/
for (int i = 0; i < count; i++) {
if (data[i] == what) {
return i;
}
}
return -1;
}
// !!! TODO this is not yet correct, because it's not being reset when
// the rest of the entries are changed
// protected void cacheIndices() {
// indexCache = new HashMap<Integer, Integer>();
// for (int i = 0; i < count; i++) {
// indexCache.put(data[i], i);
// }
// }
public boolean hasValue(float value) {
if (Float.isNaN(value)) {
for (int i = 0; i < count; i++) {
if (Float.isNaN(data[i])) {
return true;
}
}
} else {
for (int i = 0; i < count; i++) {
if (data[i] == value) {
return true;
}
}
}
return false;
}
// doesn't really make sense with float.. use add() if you need it
// public void increment(int index) {
// data[index]++;
// }
public void add(int index, float amount) {
data[index] += amount;
}
public void sub(int index, float amount) {
data[index] -= amount;
}
public void mul(int index, float amount) {
data[index] *= amount;
}
public void div(int index, float amount) {
data[index] /= amount;
}
public float min() {
if (count == 0) {
throw new ArrayIndexOutOfBoundsException("Cannot use min() on IntList of length 0.");
}
if (data.length == 0) {
return Float.NaN;
}
@@ -80,7 +424,10 @@ public class FloatList {
}
public float calcMax() {
public float max() {
if (count == 0) {
throw new ArrayIndexOutOfBoundsException("Cannot use max() on IntList of length 0.");
}
if (data.length == 0) {
return Float.NaN;
}
@@ -104,125 +451,131 @@ public class FloatList {
}
public void removeNaN() {
int index = 0;
for (int i = 0; i < count; i++) {
if (data[i] == data[i]) {
if (i != index) {
data[index] = data[i];
}
index++;
/** Sorts the array in place. */
public void sort() {
Arrays.sort(data, 0, count);
}
/** reverse sort, orders values from highest to lowest */
public void sortReverse() {
new Sort() {
@Override
public int size() {
return count;
}
}
count = index;
}
public void replaceNaN(float replacement) {
for (int i = 0; i < count; i++) {
if (data[i] != data[i]) {
data[i] = replacement;
@Override
public float compare(int a, int b) {
return data[a] - data[b];
}
}
}
public void add(float amt) {
for (int i = 0; i < count; i++) {
data[i] += amt;
}
}
public void sub(float amt) {
for (int i = 0; i < count; i++) {
data[i] -= amt;
}
}
public void mul(float amt) {
for (int i = 0; i < count; i++) {
data[i] *= amt;
}
}
public void div(float amt) {
for (int i = 0; i < count; i++) {
data[i] /= amt;
}
}
/*
static public void shuffle(int[] array) {
java.util.Random rng = new java.util.Random();
int n = array.length;
while (n > 1) {
int k = rng.nextInt(n);
n--;
int temp = array[n];
array[n] = array[k];
array[k] = temp;
@Override
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
}.run();
}
*/
private void crop() {
if (count != data.length) {
data = PApplet.subset(data, 0, count);
// 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 reverse() {
int ii = count - 1;
for (int i = 0; i < count/2; i++) {
float t = data[i];
data[i] = data[ii];
data[ii] = t;
--ii;
}
}
/**
* Randomize the order of the list elements. Note that this does not
* obey the randomSeed() function in PApplet.
*/
public void shuffle() {
Random r = new Random();
int num = count;
while (num > 1) {
int value = r.nextInt(num);
num--;
float temp = data[num];
data[num] = data[value];
data[value] = temp;
}
}
/**
* Randomize the list order using the random() function from the specified
* sketch, allowing shuffle() to use its current randomSeed() setting.
*/
public void shuffle(PApplet sketch) {
int num = count;
while (num > 1) {
int value = (int) sketch.random(num);
num--;
float temp = data[num];
data[num] = data[value];
data[value] = temp;
}
}
public FloatList copy() {
FloatList outgoing = new FloatList(data);
outgoing.count = count;
return outgoing;
}
/**
* Returns the actual array being used to store the data. Suitable for
* iterating with a for() loop, but modifying the list could cause terrible
* things to happen.
*/
public float[] values() {
crop();
return data;
}
public int[] toIntArray() {
int[] outgoing = new int[count];
for (int i = 0; i < count; i++) {
outgoing[i] = (int) data[i];
}
return outgoing;
}
public Iterator<Float> valueIterator() {
return new Iterator<Float>() {
int index = -1;
public void remove() {
FloatList.this.remove(index);
}
public long[] toLongArray() {
long[] outgoing = new long[count];
for (int i = 0; i < count; i++) {
outgoing[i] = (long) data[i];
}
return outgoing;
}
public Float next() {
return data[++index];
}
public float[] toFloatArray() {
float[] outgoing = new float[count];
System.arraycopy(data, 0, outgoing, 0, count);
return outgoing;
}
public double[] toDoubleArray() {
double[] outgoing = new double[count];
for (int i = 0; i < count; i++) {
outgoing[i] = data[i];
}
return outgoing;
}
public String[] toStringArray() {
String[] outgoing = new String[count];
for (int i = 0; i < count; i++) {
outgoing[i] = String.valueOf(data[i]);
}
return outgoing;
public boolean hasNext() {
return index+1 < count;
}
};
}
@@ -230,16 +583,20 @@ public class FloatList {
* 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 float[] toArray() {
// return toFloatArray();
// }
public int[] valueArray() {
return valueArray(null);
}
/**
* Copy as many values as possible into the specified array.
* @param array
*/
// public void toArray(float[] array) {
// System.arraycopy(data, 0, array, 0, Math.min(count, array.length));
// }
public int[] valueArray(int[] array) {
if (array == null || array.length != count) {
array = new int[count];
}
System.arraycopy(data, 0, array, 0, count);
return array;
}
}
+19 -19
View File
@@ -513,13 +513,13 @@ public class IntList {
}
public int[] toIntArray() {
int[] outgoing = new int[count];
for (int i = 0; i < count; i++) {
outgoing[i] = (int) data[i];
}
return outgoing;
}
// public int[] toIntArray() {
// int[] outgoing = new int[count];
// for (int i = 0; i < count; i++) {
// outgoing[i] = (int) data[i];
// }
// return outgoing;
// }
// public long[] toLongArray() {
@@ -531,11 +531,11 @@ public class IntList {
// }
public float[] toFloatArray() {
float[] outgoing = new float[count];
System.arraycopy(data, 0, outgoing, 0, count);
return outgoing;
}
// public float[] toFloatArray() {
// float[] outgoing = new float[count];
// System.arraycopy(data, 0, outgoing, 0, count);
// return outgoing;
// }
// public double[] toDoubleArray() {
@@ -547,11 +547,11 @@ public class IntList {
// }
public String[] toStringArray() {
String[] outgoing = new String[count];
for (int i = 0; i < count; i++) {
outgoing[i] = String.valueOf(data[i]);
}
return outgoing;
}
// public String[] toStringArray() {
// String[] outgoing = new String[count];
// for (int i = 0; i < count; i++) {
// outgoing[i] = String.valueOf(data[i]);
// }
// return outgoing;
// }
}
+24
View File
@@ -145,6 +145,30 @@ public class JSONArray {
}
public JSONArray(IntList list) {
myArrayList = new ArrayList<Object>();
for (int item : list.values()) {
myArrayList.add(new Integer(item));
}
}
public JSONArray(FloatList list) {
myArrayList = new ArrayList<Object>();
for (float item : list.values()) {
myArrayList.add(new Float(item));
}
}
public JSONArray(StringList list) {
myArrayList = new ArrayList<Object>();
for (String item : list.values()) {
myArrayList.add(item);
}
}
/**
* Construct a JSONArray from a source JSON text.
* @param source A string that begins with
+24
View File
@@ -293,6 +293,30 @@ public class JSONObject {
}
public JSONObject(IntHash dict) {
map = new HashMap<String, Object>();
for (int i = 0; i < dict.size(); i++) {
setInt(dict.key(i), dict.value(i));
}
}
public JSONObject(FloatHash dict) {
map = new HashMap<String, Object>();
for (int i = 0; i < dict.size(); i++) {
setFloat(dict.key(i), dict.value(i));
}
}
public JSONObject(StringHash dict) {
map = new HashMap<String, Object>();
for (int i = 0; i < dict.size(); i++) {
setString(dict.key(i), dict.value(i));
}
}
/**
* Construct a JSONObject from an Object using bean getters.
* It reflects on all of the public methods of the object.
+594
View File
@@ -0,0 +1,594 @@
package processing.data;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
import processing.core.PApplet;
public class StringList {
int count;
String[] data;
public StringList() {
data = new String[10];
}
public StringList(String[] list) {
count = list.length;
data = new String[count];
System.arraycopy(list, 0, data, 0, count);
}
/**
* 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.
*/
public int size() {
return count;
}
public void resize(int length) {
if (length > data.length) {
String[] temp = new String[length];
System.arraycopy(data, 0, temp, 0, count);
data = temp;
} else if (length > count) {
Arrays.fill(data, count, length, 0);
}
count = length;
}
/**
* Remove all entries from the list.
*/
public void clear() {
count = 0;
}
/**
* Get an entry at a particular index.
*/
public String get(int index) {
return data[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, String what) {
if (index >= count) {
data = PApplet.expand(data, index+1);
for (int i = count; i < index; i++) {
data[i] = null;
}
count = index+1;
}
data[index] = what;
}
/** 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--;
}
/** Remove the first instance of a particular value */
public boolean removeValue(String value) {
if (value == null) {
for (int i = 0; i < count; i++) {
if (data[i] == null) {
remove(i);
return true;
}
}
} else {
int index = index(value);
if (index != -1) {
remove(index);
return true;
}
}
return false;
}
/** Remove all instances of a particular value */
public boolean removeValues(String value) {
int ii = 0;
for (int i = 0; i < count; i++) {
if (data[i] != value) {
data[ii++] = data[i];
}
}
boolean changed = count == ii;
count = ii;
return changed;
}
public boolean replaceValue(String value, String newValue) {
if (value == null) {
for (int i = 0; i < count; i++) {
if (data[i] == null) {
data[i] = newValue;
return true;
}
}
} else {
for (int i = 0; i < count; i++) {
if (value.equals(data[i])) {
data[i] = newValue;
return true;
}
}
}
return false;
}
public boolean replaceValues(String value, String newValue) {
boolean changed = false;
if (value == null) {
for (int i = 0; i < count; i++) {
if (data[i] == null) {
data[i] = newValue;
changed = true;
}
}
} else {
for (int i = 0; i < count; i++) {
if (value.equals(data[i])) {
data[i] = newValue;
changed = true;
}
}
}
return changed;
}
/** Add a new entry to the list. */
public void append(String value) {
if (count == data.length) {
data = PApplet.expand(data);
}
data[count++] = value;
}
public void append(String[] values) {
for (String v : values) {
append(v);
}
}
public void append(StringList list) {
for (String v : list.values()) { // will concat the list...
append(v);
}
}
// 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) {
throw new IllegalArgumentException("insert() index cannot be negative: it was " + index);
}
if (index >= values.length) {
throw new IllegalArgumentException("insert() index " + index + " is past the end of this list");
}
String[] temp = new String[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;
}
public void insert(int index, IntList list) {
insert(index, list.values());
}
// 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++;
// }
/** Return the first index of a particular value. */
public int index(String what) {
if (what == null) {
for (int i = 0; i < count; i++) {
if (data[i] == null) {
return i;
}
}
} else {
for (int i = 0; i < count; i++) {
if (what.equals(data[i])) {
return i;
}
}
}
return -1;
}
// !!! TODO this is not yet correct, because it's not being reset when
// the rest of the entries are changed
// protected void cacheIndices() {
// indexCache = new HashMap<Integer, Integer>();
// for (int i = 0; i < count; i++) {
// indexCache.put(data[i], i);
// }
// }
public boolean hasValue(String value) {
if (value == null) {
for (int i = 0; i < count; i++) {
if (data[i] == null) {
return true;
}
}
} else {
for (int i = 0; i < count; i++) {
if (value.equals(data[i])) {
return true;
}
}
}
return false;
}
// public void increment(int index) {
// data[index]++;
// }
//
//
// public void add(int index, int amount) {
// data[index] += amount;
// }
//
//
// public void sub(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 String min() {
// if (count == 0) {
// throw new ArrayIndexOutOfBoundsException("Cannot use min() on IntList of length 0.");
// }
// if (data.length == 0) {
// return String.NaN;
// }
// String m = Float.NaN;
// for (int i = 0; i < data.length; i++) {
// // find one good value to start
// if (data[i] == data[i]) {
// m = data[i];
//
// // calculate the rest
// for (int j = i+1; j < data.length; j++) {
// float d = data[j];
// if (!Float.isNaN(d) && (d < m)) {
// m = data[j];
// }
// }
// break;
// }
// }
// return m;
// }
// public float max() {
// if (count == 0) {
// throw new ArrayIndexOutOfBoundsException("Cannot use max() on IntList of length 0.");
// }
// if (data.length == 0) {
// return Float.NaN;
// }
// float m = Float.NaN;
// for (int i = 0; i < data.length; i++) {
// // find one good value to start
// if (data[i] == data[i]) {
// m = data[i];
//
// // calculate the rest
// for (int j = i+1; j < data.length; j++) {
// float d = data[j];
// if (!Float.isNaN(d) && (d > m)) {
// m = data[j];
// }
// }
// break;
// }
// }
// return m;
// }
/** Sorts the array in place. */
public void sort() {
sortImpl(false);
}
/** reverse sort, orders values from highest to lowest */
public void sortReverse() {
sortImpl(true);
}
private void sortImpl(final boolean reverse) {
new Sort() {
@Override
public int size() {
return count;
}
@Override
public float compare(int a, int b) {
float diff = data[a].compareToIgnoreCase(data[b]);
return reverse ? -diff : diff;
}
@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 reverse() {
int ii = count - 1;
for (int i = 0; i < count/2; i++) {
String t = data[i];
data[i] = data[ii];
data[ii] = t;
--ii;
}
}
/**
* Randomize the order of the list elements. Note that this does not
* obey the randomSeed() function in PApplet.
*/
public void shuffle() {
Random r = new Random();
int num = count;
while (num > 1) {
int value = r.nextInt(num);
num--;
String temp = data[num];
data[num] = data[value];
data[value] = temp;
}
}
/**
* Randomize the list order using the random() function from the specified
* sketch, allowing shuffle() to use its current randomSeed() setting.
*/
public void shuffle(PApplet sketch) {
int num = count;
while (num > 1) {
int value = (int) sketch.random(num);
num--;
String temp = data[num];
data[num] = data[value];
data[value] = temp;
}
}
public StringList copy() {
StringList outgoing = new StringList(data);
outgoing.count = count;
return outgoing;
}
/**
* Returns the actual array being used to store the data. Suitable for
* iterating with a for() loop, but modifying the list could cause terrible
* things to happen.
*/
public String[] values() {
crop();
return data;
}
public Iterator<String> valueIterator() {
return new Iterator<String>() {
int index = -1;
public void remove() {
StringList.this.remove(index);
}
public String next() {
return data[++index];
}
public boolean hasNext() {
return index+1 < count;
}
};
}
/**
* 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[] valueArray() {
return valueArray(null);
}
/**
* Copy as many values as possible into the specified array.
* @param array
*/
public int[] valueArray(int[] array) {
if (array == null || array.length != count) {
array = new int[count];
}
System.arraycopy(data, 0, array, 0, count);
return array;
}
}
+4
View File
@@ -24,6 +24,8 @@ _ rsort(), sortReverse(), sortKeysReverse,
_ sortDescend, sortDescending, sortKeysDescending,
_ sortHighLow, sortHigh, sortHighest, sortDown
"hash.toJSONObject()" or "new JSONObject(hash)"
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()
@@ -51,6 +53,8 @@ _ could use an int array instead, but a bit hokey in places
replace? (especially for NaN)
match? find? on StringList?
decide on TableODS, TableHTML
Iterable, Iterator, or [] returned for keys(), rows(), etc.
list, dict, json, table are each more efficient at different things
keys(), rows(), etc. should return something Iterable