propane 3.1.0.pre-java → 3.2.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/CHANGELOG.md +1 -5
- data/README.md +23 -12
- data/Rakefile +23 -12
- data/lib/propane/helpers/version_error.rb +6 -0
- data/lib/propane/runner.rb +12 -0
- data/lib/propane/version.rb +1 -1
- data/library/slider/slider.rb +1 -1
- data/mvnw +234 -0
- data/mvnw.cmd +145 -0
- data/pom.xml +28 -27
- data/propane.gemspec +2 -2
- data/src/main/java/japplemenubar/JAppleMenuBar.java +41 -47
- data/src/main/java/monkstone/ColorUtil.java +1 -1
- data/src/main/java/monkstone/MathToolModule.java +12 -11
- data/src/main/java/monkstone/PropaneLibrary.java +9 -10
- data/src/main/java/monkstone/core/LibraryProxy.java +124 -113
- data/src/main/java/monkstone/fastmath/Deglut.java +86 -89
- data/src/main/java/monkstone/filechooser/Chooser.java +7 -13
- data/src/main/java/monkstone/noise/SimplexNoise.java +0 -1
- data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +4 -4
- data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +9 -9
- data/src/main/java/monkstone/slider/SimpleSlider.java +0 -9
- data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +11 -13
- data/src/main/java/monkstone/slider/Slider.java +1 -1
- data/src/main/java/monkstone/slider/SliderBar.java +1 -1
- data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
- data/src/main/java/monkstone/slider/WheelHandler.java +8 -9
- data/src/main/java/monkstone/vecmath/AppRender.java +2 -2
- data/src/main/java/monkstone/vecmath/ShapeRender.java +2 -2
- data/src/main/java/monkstone/vecmath/package-info.java +2 -2
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
- data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
- data/src/main/java/monkstone/videoevent/VideoInterface.java +11 -5
- data/src/main/java/monkstone/videoevent/package-info.java +2 -2
- data/src/main/java/processing/awt/PGraphicsJava2D.java +1742 -2243
- data/src/main/java/processing/awt/PShapeJava2D.java +268 -270
- data/src/main/java/processing/awt/PSurfaceAWT.java +821 -920
- data/src/main/java/processing/core/DesktopHandler.java +94 -0
- data/src/main/java/processing/core/PApplet.java +14170 -14082
- data/src/main/java/processing/core/PConstants.java +447 -473
- data/src/main/java/processing/core/PFont.java +867 -873
- data/src/main/java/processing/core/PGraphics.java +7193 -7428
- data/src/main/java/processing/core/PImage.java +3051 -3117
- data/src/main/java/processing/core/PMatrix.java +159 -172
- data/src/main/java/processing/core/PMatrix2D.java +403 -444
- data/src/main/java/processing/core/PMatrix3D.java +735 -749
- data/src/main/java/processing/core/PShape.java +2651 -2793
- data/src/main/java/processing/core/PShapeOBJ.java +415 -422
- data/src/main/java/processing/core/PShapeSVG.java +1466 -1475
- data/src/main/java/processing/core/PStyle.java +37 -40
- data/src/main/java/processing/core/PSurface.java +98 -103
- data/src/main/java/processing/core/PSurfaceNone.java +208 -236
- data/src/main/java/processing/core/PVector.java +961 -990
- data/src/main/java/processing/data/DoubleDict.java +709 -753
- data/src/main/java/processing/data/DoubleList.java +695 -748
- data/src/main/java/processing/data/FloatDict.java +702 -746
- data/src/main/java/processing/data/FloatList.java +697 -751
- data/src/main/java/processing/data/IntDict.java +673 -718
- data/src/main/java/processing/data/IntList.java +633 -699
- data/src/main/java/processing/data/JSONArray.java +873 -931
- data/src/main/java/processing/data/JSONObject.java +1165 -1262
- data/src/main/java/processing/data/JSONTokener.java +341 -351
- data/src/main/java/processing/data/LongDict.java +662 -707
- data/src/main/java/processing/data/LongList.java +634 -700
- data/src/main/java/processing/data/Sort.java +41 -37
- data/src/main/java/processing/data/StringDict.java +486 -522
- data/src/main/java/processing/data/StringList.java +580 -624
- data/src/main/java/processing/data/Table.java +3508 -3686
- data/src/main/java/processing/data/TableRow.java +183 -182
- data/src/main/java/processing/data/XML.java +883 -957
- data/src/main/java/processing/event/Event.java +66 -87
- data/src/main/java/processing/event/KeyEvent.java +41 -48
- data/src/main/java/processing/event/MouseEvent.java +93 -103
- data/src/main/java/processing/event/TouchEvent.java +6 -10
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +5 -69
- data/src/main/java/processing/javafx/PSurfaceFX.java +2 -7
- data/src/main/java/processing/opengl/FontTexture.java +270 -290
- data/src/main/java/processing/opengl/FrameBuffer.java +363 -375
- data/src/main/java/processing/opengl/LinePath.java +500 -543
- data/src/main/java/processing/opengl/LineStroker.java +582 -593
- data/src/main/java/processing/opengl/PGL.java +2881 -2904
- data/src/main/java/processing/opengl/PGraphics2D.java +315 -408
- data/src/main/java/processing/opengl/PGraphics3D.java +72 -107
- data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12043 -12230
- data/src/main/java/processing/opengl/PJOGL.java +1681 -1745
- data/src/main/java/processing/opengl/PShader.java +1257 -1260
- data/src/main/java/processing/opengl/PShapeOpenGL.java +4599 -4662
- data/src/main/java/processing/opengl/PSurfaceJOGL.java +1030 -1047
- data/src/main/java/processing/opengl/Texture.java +1397 -1462
- data/src/main/java/processing/opengl/VertexBuffer.java +55 -57
- data/src/main/resources/icon/icon-1024.png +0 -0
- data/src/main/resources/icon/icon-128.png +0 -0
- data/src/main/resources/icon/icon-16.png +0 -0
- data/src/main/resources/icon/icon-256.png +0 -0
- data/src/main/resources/icon/icon-32.png +0 -0
- data/src/main/resources/icon/icon-48.png +0 -0
- data/src/main/resources/icon/icon-512.png +0 -0
- data/src/main/resources/icon/icon-64.png +0 -0
- data/vendors/Rakefile +1 -1
- metadata +12 -8
- data/src/main/java/processing/core/ThinkDifferent.java +0 -70
|
@@ -1,46 +1,50 @@
|
|
|
1
1
|
package processing.data;
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
/**
|
|
5
|
-
* Internal sorter used by several data classes.
|
|
6
|
-
*
|
|
4
|
+
* Internal sorter used by several data classes. Advanced users only, not
|
|
5
|
+
* official API.
|
|
7
6
|
*/
|
|
8
7
|
public abstract class Sort implements Runnable {
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
public Sort() {
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public void run() {
|
|
13
|
+
int c = size();
|
|
14
|
+
if (c > 1) {
|
|
15
|
+
sort(0, c - 1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
11
18
|
|
|
19
|
+
protected void sort(int i, int j) {
|
|
20
|
+
int pivotIndex = (i + j) / 2;
|
|
21
|
+
swap(pivotIndex, j);
|
|
22
|
+
int k = partition(i - 1, j);
|
|
23
|
+
swap(k, j);
|
|
24
|
+
if ((k - i) > 1) {
|
|
25
|
+
sort(i, k - 1);
|
|
26
|
+
}
|
|
27
|
+
if ((j - k) > 1) {
|
|
28
|
+
sort(k + 1, j);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
12
31
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
protected int partition(int left, int right) {
|
|
33
|
+
int pivot = right;
|
|
34
|
+
do {
|
|
35
|
+
while (compare(++left, pivot) < 0) {
|
|
36
|
+
}
|
|
37
|
+
while ((right != 0) && (compare(--right, pivot) > 0)) {
|
|
38
|
+
}
|
|
39
|
+
swap(left, right);
|
|
40
|
+
} while (left < right);
|
|
41
|
+
swap(left, right);
|
|
42
|
+
return left;
|
|
17
43
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
swap(
|
|
24
|
-
|
|
25
|
-
swap(k, j);
|
|
26
|
-
if ((k-i) > 1) sort(i, k-1);
|
|
27
|
-
if ((j-k) > 1) sort(k+1, j);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
protected int partition(int left, int right) {
|
|
32
|
-
int pivot = right;
|
|
33
|
-
do {
|
|
34
|
-
while (compare(++left, pivot) < 0) { }
|
|
35
|
-
while ((right != 0) && (compare(--right, pivot) > 0)) { }
|
|
36
|
-
swap(left, right);
|
|
37
|
-
} while (left < right);
|
|
38
|
-
swap(left, right);
|
|
39
|
-
return left;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
abstract public int size();
|
|
44
|
-
abstract public int compare(int a, int b);
|
|
45
|
-
abstract public void swap(int a, int b);
|
|
46
|
-
}
|
|
44
|
+
|
|
45
|
+
abstract public int size();
|
|
46
|
+
|
|
47
|
+
abstract public int compare(int a, int b);
|
|
48
|
+
|
|
49
|
+
abstract public void swap(int a, int b);
|
|
50
|
+
}
|
|
@@ -6,7 +6,6 @@ import java.util.Iterator;
|
|
|
6
6
|
|
|
7
7
|
import processing.core.PApplet;
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* A simple table class to use a String as a lookup for another String value.
|
|
12
11
|
*
|
|
@@ -16,595 +15,560 @@ import processing.core.PApplet;
|
|
|
16
15
|
*/
|
|
17
16
|
public class StringDict {
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
protected String[] values;
|
|
24
|
-
|
|
25
|
-
/** Internal implementation for faster lookups */
|
|
26
|
-
private HashMap<String, Integer> indices = new HashMap<>();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
public StringDict() {
|
|
30
|
-
count = 0;
|
|
31
|
-
keys = new String[10];
|
|
32
|
-
values = new String[10];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Create a new lookup pre-allocated to a specific length. This will not
|
|
38
|
-
* change the size(), but is more efficient than not specifying a length.
|
|
39
|
-
* Use it when you know the rough size of the thing you're creating.
|
|
40
|
-
*
|
|
41
|
-
* @nowebref
|
|
42
|
-
*/
|
|
43
|
-
public StringDict(int length) {
|
|
44
|
-
count = 0;
|
|
45
|
-
keys = new String[length];
|
|
46
|
-
values = new String[length];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Read a set of entries from a Reader that has each key/value pair on
|
|
52
|
-
* a single line, separated by a tab.
|
|
53
|
-
*
|
|
54
|
-
* @nowebref
|
|
55
|
-
*/
|
|
56
|
-
public StringDict(BufferedReader reader) {
|
|
57
|
-
String[] lines = PApplet.loadStrings(reader);
|
|
58
|
-
keys = new String[lines.length];
|
|
59
|
-
values = new String[lines.length];
|
|
60
|
-
|
|
61
|
-
for (int i = 0; i < lines.length; i++) {
|
|
62
|
-
String[] pieces = PApplet.split(lines[i], '\t');
|
|
63
|
-
if (pieces.length == 2) {
|
|
64
|
-
keys[count] = pieces[0];
|
|
65
|
-
values[count] = pieces[1];
|
|
66
|
-
indices.put(keys[count], count);
|
|
67
|
-
count++;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @nowebref
|
|
75
|
-
*/
|
|
76
|
-
public StringDict(String[] keys, String[] values) {
|
|
77
|
-
if (keys.length != values.length) {
|
|
78
|
-
throw new IllegalArgumentException("key and value arrays must be the same length");
|
|
79
|
-
}
|
|
80
|
-
this.keys = keys;
|
|
81
|
-
this.values = values;
|
|
82
|
-
count = keys.length;
|
|
83
|
-
for (int i = 0; i < count; i++) {
|
|
84
|
-
indices.put(keys[i], i);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Constructor to allow (more intuitive) inline initialization, e.g.:
|
|
91
|
-
* <pre>
|
|
92
|
-
* new StringDict(new String[][] {
|
|
93
|
-
* { "key1", "value1" },
|
|
94
|
-
* { "key2", "value2" }
|
|
95
|
-
* });
|
|
96
|
-
* </pre>
|
|
97
|
-
* It's no Python, but beats a static { } block with HashMap.put() statements.
|
|
98
|
-
*/
|
|
99
|
-
public StringDict(String[][] pairs) {
|
|
100
|
-
count = pairs.length;
|
|
101
|
-
this.keys = new String[count];
|
|
102
|
-
this.values = new String[count];
|
|
103
|
-
for (int i = 0; i < count; i++) {
|
|
104
|
-
keys[i] = pairs[i][0];
|
|
105
|
-
values[i] = pairs[i][1];
|
|
106
|
-
indices.put(keys[i], i);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
18
|
+
/**
|
|
19
|
+
* Number of elements in the table
|
|
20
|
+
*/
|
|
21
|
+
protected int count;
|
|
109
22
|
|
|
23
|
+
protected String[] keys;
|
|
24
|
+
protected String[] values;
|
|
110
25
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
*/
|
|
116
|
-
public StringDict(TableRow row) {
|
|
117
|
-
this(row.getColumnCount());
|
|
26
|
+
/**
|
|
27
|
+
* Internal implementation for faster lookups
|
|
28
|
+
*/
|
|
29
|
+
private HashMap<String, Integer> indices = new HashMap<>();
|
|
118
30
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for (int col = 0; col < row.getColumnCount(); col++) {
|
|
124
|
-
set(titles[col], row.getString(col));
|
|
31
|
+
public StringDict() {
|
|
32
|
+
count = 0;
|
|
33
|
+
keys = new String[10];
|
|
34
|
+
values = new String[10];
|
|
125
35
|
}
|
|
126
|
-
// remove unused and overwritten entries
|
|
127
|
-
crop();
|
|
128
|
-
}
|
|
129
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Create a new lookup pre-allocated to a specific length. This will not
|
|
39
|
+
* change the size(), but is more efficient than not specifying a length.
|
|
40
|
+
* Use it when you know the rough size of the thing you're creating.
|
|
41
|
+
*
|
|
42
|
+
* @nowebref
|
|
43
|
+
*/
|
|
44
|
+
public StringDict(int length) {
|
|
45
|
+
count = 0;
|
|
46
|
+
keys = new String[length];
|
|
47
|
+
values = new String[length];
|
|
48
|
+
}
|
|
130
49
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Read a set of entries from a Reader that has each key/value pair on a
|
|
52
|
+
* single line, separated by a tab.
|
|
53
|
+
*
|
|
54
|
+
* @nowebref
|
|
55
|
+
*/
|
|
56
|
+
public StringDict(BufferedReader reader) {
|
|
57
|
+
String[] lines = PApplet.loadStrings(reader);
|
|
58
|
+
keys = new String[lines.length];
|
|
59
|
+
values = new String[lines.length];
|
|
60
|
+
|
|
61
|
+
for (int i = 0; i < lines.length; i++) {
|
|
62
|
+
String[] pieces = PApplet.split(lines[i], '\t');
|
|
63
|
+
if (pieces.length == 2) {
|
|
64
|
+
keys[count] = pieces[0];
|
|
65
|
+
values[count] = pieces[1];
|
|
66
|
+
indices.put(keys[count], count);
|
|
67
|
+
count++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
138
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @nowebref
|
|
74
|
+
*/
|
|
75
|
+
public StringDict(String[] keys, String[] values) {
|
|
76
|
+
if (keys.length != values.length) {
|
|
77
|
+
throw new IllegalArgumentException("key and value arrays must be the same length");
|
|
78
|
+
}
|
|
79
|
+
this.keys = keys;
|
|
80
|
+
this.values = values;
|
|
81
|
+
count = keys.length;
|
|
82
|
+
for (int i = 0; i < count; i++) {
|
|
83
|
+
indices.put(keys[i], i);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
139
86
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Constructor to allow (more intuitive) inline initialization, e.g.:
|
|
89
|
+
* <pre>
|
|
90
|
+
* new StringDict(new String[][] {
|
|
91
|
+
* { "key1", "value1" },
|
|
92
|
+
* { "key2", "value2" }
|
|
93
|
+
* });
|
|
94
|
+
* </pre> It's no Python, but beats a static { } block with HashMap.put()
|
|
95
|
+
* statements.
|
|
96
|
+
*/
|
|
97
|
+
public StringDict(String[][] pairs) {
|
|
98
|
+
count = pairs.length;
|
|
99
|
+
this.keys = new String[count];
|
|
100
|
+
this.values = new String[count];
|
|
101
|
+
for (int i = 0; i < count; i++) {
|
|
102
|
+
keys[i] = pairs[i][0];
|
|
103
|
+
values[i] = pairs[i][1];
|
|
104
|
+
indices.put(keys[i], i);
|
|
105
|
+
}
|
|
147
106
|
}
|
|
148
|
-
|
|
149
|
-
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create a dictionary that maps between column titles and cell entries in a
|
|
110
|
+
* TableRow. If two columns have the same name, the later column's values
|
|
111
|
+
* will override the earlier values.
|
|
112
|
+
*/
|
|
113
|
+
public StringDict(TableRow row) {
|
|
114
|
+
this(row.getColumnCount());
|
|
115
|
+
|
|
116
|
+
String[] titles = row.getColumnTitles();
|
|
117
|
+
if (titles == null) {
|
|
118
|
+
titles = new StringList(IntList.fromRange(row.getColumnCount())).array();
|
|
119
|
+
}
|
|
120
|
+
for (int col = 0; col < row.getColumnCount(); col++) {
|
|
121
|
+
set(titles[col], row.getString(col));
|
|
122
|
+
}
|
|
123
|
+
// remove unused and overwritten entries
|
|
124
|
+
crop();
|
|
150
125
|
}
|
|
151
126
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
resetIndices();
|
|
160
|
-
}
|
|
127
|
+
/**
|
|
128
|
+
* @webref stringdict:method
|
|
129
|
+
* @brief Returns the number of key/value pairs
|
|
130
|
+
*/
|
|
131
|
+
public int size() {
|
|
132
|
+
return count;
|
|
133
|
+
}
|
|
161
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Resize the internal data, this can only be used to shrink the list.
|
|
137
|
+
* Helpful for situations like sorting and then grabbing the top 50 entries.
|
|
138
|
+
*/
|
|
139
|
+
public void resize(int length) {
|
|
140
|
+
if (length > count) {
|
|
141
|
+
throw new IllegalArgumentException("resize() can only be used to shrink the dictionary");
|
|
142
|
+
}
|
|
143
|
+
if (length < 1) {
|
|
144
|
+
throw new IllegalArgumentException("resize(" + length + ") is too small, use 1 or higher");
|
|
145
|
+
}
|
|
162
146
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
147
|
+
String[] newKeys = new String[length];
|
|
148
|
+
String[] newValues = new String[length];
|
|
149
|
+
PApplet.arrayCopy(keys, newKeys, length);
|
|
150
|
+
PApplet.arrayCopy(values, newValues, length);
|
|
151
|
+
keys = newKeys;
|
|
152
|
+
values = newValues;
|
|
153
|
+
count = length;
|
|
154
|
+
resetIndices();
|
|
155
|
+
}
|
|
173
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Remove all entries.
|
|
159
|
+
*
|
|
160
|
+
* @webref stringdict:method
|
|
161
|
+
* @brief Remove all entries
|
|
162
|
+
*/
|
|
163
|
+
public void clear() {
|
|
164
|
+
count = 0;
|
|
165
|
+
indices = new HashMap<>();
|
|
166
|
+
}
|
|
174
167
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
168
|
+
private void resetIndices() {
|
|
169
|
+
indices = new HashMap<>(count);
|
|
170
|
+
for (int i = 0; i < count; i++) {
|
|
171
|
+
indices.put(keys[i], i);
|
|
172
|
+
}
|
|
179
173
|
}
|
|
180
|
-
}
|
|
181
174
|
|
|
175
|
+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
176
|
+
public class Entry {
|
|
182
177
|
|
|
183
|
-
|
|
178
|
+
public String key;
|
|
179
|
+
public String value;
|
|
184
180
|
|
|
181
|
+
Entry(String key, String value) {
|
|
182
|
+
this.key = key;
|
|
183
|
+
this.value = value;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
185
186
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
public String value;
|
|
187
|
+
public Iterable<Entry> entries() {
|
|
188
|
+
return new Iterable<Entry>() {
|
|
189
189
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
public Iterator<Entry> iterator() {
|
|
191
|
+
return entryIterator();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
193
194
|
}
|
|
194
|
-
}
|
|
195
195
|
|
|
196
|
+
public Iterator<Entry> entryIterator() {
|
|
197
|
+
return new Iterator<Entry>() {
|
|
198
|
+
int index = -1;
|
|
199
|
+
|
|
200
|
+
public void remove() {
|
|
201
|
+
removeIndex(index);
|
|
202
|
+
index--;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public Entry next() {
|
|
206
|
+
++index;
|
|
207
|
+
Entry e = new Entry(keys[index], values[index]);
|
|
208
|
+
return e;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public boolean hasNext() {
|
|
212
|
+
return index + 1 < size();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return entryIterator();
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
217
|
+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
218
|
+
public String key(int index) {
|
|
219
|
+
return keys[index];
|
|
220
|
+
}
|
|
205
221
|
|
|
222
|
+
protected void crop() {
|
|
223
|
+
if (count != keys.length) {
|
|
224
|
+
keys = PApplet.subset(keys, 0, count);
|
|
225
|
+
values = PApplet.subset(values, 0, count);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
206
228
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
int index = -1;
|
|
229
|
+
public Iterable<String> keys() {
|
|
230
|
+
return new Iterable<String>() {
|
|
210
231
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
232
|
+
@Override
|
|
233
|
+
public Iterator<String> iterator() {
|
|
234
|
+
return keyIterator();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
215
238
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
239
|
+
// Use this to iterate when you want to be able to remove elements along the way
|
|
240
|
+
public Iterator<String> keyIterator() {
|
|
241
|
+
return new Iterator<String>() {
|
|
242
|
+
int index = -1;
|
|
221
243
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
244
|
+
public void remove() {
|
|
245
|
+
removeIndex(index);
|
|
246
|
+
index--;
|
|
247
|
+
}
|
|
227
248
|
|
|
249
|
+
public String next() {
|
|
250
|
+
return key(++index);
|
|
251
|
+
}
|
|
228
252
|
|
|
229
|
-
|
|
253
|
+
public boolean hasNext() {
|
|
254
|
+
return index + 1 < size();
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
230
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Return a copy of the internal keys array. This array can be modified.
|
|
261
|
+
*
|
|
262
|
+
* @webref stringdict:method
|
|
263
|
+
* @brief Return a copy of the internal keys array
|
|
264
|
+
*/
|
|
265
|
+
public String[] keyArray() {
|
|
266
|
+
crop();
|
|
267
|
+
return keyArray(null);
|
|
268
|
+
}
|
|
231
269
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
270
|
+
public String[] keyArray(String[] outgoing) {
|
|
271
|
+
if (outgoing == null || outgoing.length != count) {
|
|
272
|
+
outgoing = new String[count];
|
|
273
|
+
}
|
|
274
|
+
System.arraycopy(keys, 0, outgoing, 0, count);
|
|
275
|
+
return outgoing;
|
|
276
|
+
}
|
|
235
277
|
|
|
278
|
+
public String value(int index) {
|
|
279
|
+
return values[index];
|
|
280
|
+
}
|
|
236
281
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
282
|
+
/**
|
|
283
|
+
* @webref stringdict:method
|
|
284
|
+
* @brief Return the internal array being used to store the values
|
|
285
|
+
*/
|
|
286
|
+
public Iterable<String> values() {
|
|
287
|
+
return new Iterable<String>() {
|
|
288
|
+
|
|
289
|
+
@Override
|
|
290
|
+
public Iterator<String> iterator() {
|
|
291
|
+
return valueIterator();
|
|
292
|
+
}
|
|
293
|
+
};
|
|
241
294
|
}
|
|
242
|
-
}
|
|
243
295
|
|
|
296
|
+
public Iterator<String> valueIterator() {
|
|
297
|
+
return new Iterator<String>() {
|
|
298
|
+
int index = -1;
|
|
244
299
|
|
|
245
|
-
|
|
246
|
-
|
|
300
|
+
public void remove() {
|
|
301
|
+
removeIndex(index);
|
|
302
|
+
index--;
|
|
303
|
+
}
|
|
247
304
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
}
|
|
305
|
+
public String next() {
|
|
306
|
+
return value(++index);
|
|
307
|
+
}
|
|
254
308
|
|
|
309
|
+
public boolean hasNext() {
|
|
310
|
+
return index + 1 < size();
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
255
314
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Create a new array and copy each of the values into it.
|
|
317
|
+
*
|
|
318
|
+
* @webref stringdict:method
|
|
319
|
+
* @brief Create a new array and copy each of the values into it
|
|
320
|
+
*/
|
|
321
|
+
public String[] valueArray() {
|
|
322
|
+
crop();
|
|
323
|
+
return valueArray(null);
|
|
324
|
+
}
|
|
260
325
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Fill an already-allocated array with the values (more efficient than
|
|
328
|
+
* creating a new array each time). If 'array' is null, or not the same size
|
|
329
|
+
* as the number of values, a new array will be allocated and returned.
|
|
330
|
+
*/
|
|
331
|
+
public String[] valueArray(String[] array) {
|
|
332
|
+
if (array == null || array.length != size()) {
|
|
333
|
+
array = new String[count];
|
|
334
|
+
}
|
|
335
|
+
System.arraycopy(values, 0, array, 0, count);
|
|
336
|
+
return array;
|
|
337
|
+
}
|
|
265
338
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
339
|
+
/**
|
|
340
|
+
* Return a value for the specified key.
|
|
341
|
+
*
|
|
342
|
+
* @webref stringdict:method
|
|
343
|
+
* @brief Return a value for the specified key
|
|
344
|
+
*/
|
|
345
|
+
public String get(String key) {
|
|
346
|
+
int index = index(key);
|
|
347
|
+
if (index == -1) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
return values[index];
|
|
351
|
+
}
|
|
269
352
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
353
|
+
public String get(String key, String alternate) {
|
|
354
|
+
int index = index(key);
|
|
355
|
+
if (index == -1) {
|
|
356
|
+
return alternate;
|
|
357
|
+
}
|
|
358
|
+
return values[index];
|
|
359
|
+
}
|
|
275
360
|
|
|
361
|
+
/**
|
|
362
|
+
* @webref stringdict:method
|
|
363
|
+
* @brief Create a new key/value pair or change the value of one
|
|
364
|
+
*/
|
|
365
|
+
public void set(String key, String value) {
|
|
366
|
+
int index = index(key);
|
|
367
|
+
if (index == -1) {
|
|
368
|
+
create(key, value);
|
|
369
|
+
} else {
|
|
370
|
+
values[index] = value;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
276
373
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
crop();
|
|
285
|
-
return keyArray(null);
|
|
286
|
-
}
|
|
374
|
+
public void setIndex(int index, String key, String value) {
|
|
375
|
+
if (index < 0 || index >= count) {
|
|
376
|
+
throw new ArrayIndexOutOfBoundsException(index);
|
|
377
|
+
}
|
|
378
|
+
keys[index] = key;
|
|
379
|
+
values[index] = value;
|
|
380
|
+
}
|
|
287
381
|
|
|
382
|
+
public int index(String what) {
|
|
383
|
+
Integer found = indices.get(what);
|
|
384
|
+
return (found == null) ? -1 : found.intValue();
|
|
385
|
+
}
|
|
288
386
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
387
|
+
/**
|
|
388
|
+
* @webref stringdict:method
|
|
389
|
+
* @brief Check if a key is a part of the data structure
|
|
390
|
+
*/
|
|
391
|
+
public boolean hasKey(String key) {
|
|
392
|
+
return index(key) != -1;
|
|
393
|
+
}
|
|
296
394
|
|
|
395
|
+
protected void create(String key, String value) {
|
|
396
|
+
if (count == keys.length) {
|
|
397
|
+
keys = PApplet.expand(keys);
|
|
398
|
+
values = PApplet.expand(values);
|
|
399
|
+
}
|
|
400
|
+
indices.put(key, Integer.valueOf(count));
|
|
401
|
+
keys[count] = key;
|
|
402
|
+
values[count] = value;
|
|
403
|
+
count++;
|
|
404
|
+
}
|
|
297
405
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
@Override
|
|
310
|
-
public Iterator<String> iterator() {
|
|
311
|
-
return valueIterator();
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
public Iterator<String> valueIterator() {
|
|
318
|
-
return new Iterator<String>() {
|
|
319
|
-
int index = -1;
|
|
406
|
+
/**
|
|
407
|
+
* @webref stringdict:method
|
|
408
|
+
* @brief Remove a key/value pair
|
|
409
|
+
*/
|
|
410
|
+
public int remove(String key) {
|
|
411
|
+
int index = index(key);
|
|
412
|
+
if (index != -1) {
|
|
413
|
+
removeIndex(index);
|
|
414
|
+
}
|
|
415
|
+
return index;
|
|
416
|
+
}
|
|
320
417
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
418
|
+
public String removeIndex(int index) {
|
|
419
|
+
if (index < 0 || index >= count) {
|
|
420
|
+
throw new ArrayIndexOutOfBoundsException(index);
|
|
421
|
+
}
|
|
422
|
+
//System.out.println("index is " + which + " and " + keys[which]);
|
|
423
|
+
String key = keys[index];
|
|
424
|
+
indices.remove(key);
|
|
425
|
+
for (int i = index; i < count - 1; i++) {
|
|
426
|
+
keys[i] = keys[i + 1];
|
|
427
|
+
values[i] = values[i + 1];
|
|
428
|
+
indices.put(keys[i], i);
|
|
429
|
+
}
|
|
430
|
+
count--;
|
|
431
|
+
keys[count] = null;
|
|
432
|
+
values[count] = null;
|
|
433
|
+
return key;
|
|
434
|
+
}
|
|
325
435
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Create a new array and copy each of the values into it.
|
|
339
|
-
*
|
|
340
|
-
* @webref stringdict:method
|
|
341
|
-
* @brief Create a new array and copy each of the values into it
|
|
342
|
-
*/
|
|
343
|
-
public String[] valueArray() {
|
|
344
|
-
crop();
|
|
345
|
-
return valueArray(null);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Fill an already-allocated array with the values (more efficient than
|
|
351
|
-
* creating a new array each time). If 'array' is null, or not the same
|
|
352
|
-
* size as the number of values, a new array will be allocated and returned.
|
|
353
|
-
*/
|
|
354
|
-
public String[] valueArray(String[] array) {
|
|
355
|
-
if (array == null || array.length != size()) {
|
|
356
|
-
array = new String[count];
|
|
357
|
-
}
|
|
358
|
-
System.arraycopy(values, 0, array, 0, count);
|
|
359
|
-
return array;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Return a value for the specified key.
|
|
365
|
-
*
|
|
366
|
-
* @webref stringdict:method
|
|
367
|
-
* @brief Return a value for the specified key
|
|
368
|
-
*/
|
|
369
|
-
public String get(String key) {
|
|
370
|
-
int index = index(key);
|
|
371
|
-
if (index == -1) return null;
|
|
372
|
-
return values[index];
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
public String get(String key, String alternate) {
|
|
377
|
-
int index = index(key);
|
|
378
|
-
if (index == -1) return alternate;
|
|
379
|
-
return values[index];
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* @webref stringdict:method
|
|
385
|
-
* @brief Create a new key/value pair or change the value of one
|
|
386
|
-
*/
|
|
387
|
-
public void set(String key, String value) {
|
|
388
|
-
int index = index(key);
|
|
389
|
-
if (index == -1) {
|
|
390
|
-
create(key, value);
|
|
391
|
-
} else {
|
|
392
|
-
values[index] = value;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
public void setIndex(int index, String key, String value) {
|
|
398
|
-
if (index < 0 || index >= count) {
|
|
399
|
-
throw new ArrayIndexOutOfBoundsException(index);
|
|
400
|
-
}
|
|
401
|
-
keys[index] = key;
|
|
402
|
-
values[index] = value;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
public int index(String what) {
|
|
407
|
-
Integer found = indices.get(what);
|
|
408
|
-
return (found == null) ? -1 : found.intValue();
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* @webref stringdict:method
|
|
414
|
-
* @brief Check if a key is a part of the data structure
|
|
415
|
-
*/
|
|
416
|
-
public boolean hasKey(String key) {
|
|
417
|
-
return index(key) != -1;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
protected void create(String key, String value) {
|
|
422
|
-
if (count == keys.length) {
|
|
423
|
-
keys = PApplet.expand(keys);
|
|
424
|
-
values = PApplet.expand(values);
|
|
425
|
-
}
|
|
426
|
-
indices.put(key, Integer.valueOf(count));
|
|
427
|
-
keys[count] = key;
|
|
428
|
-
values[count] = value;
|
|
429
|
-
count++;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* @webref stringdict:method
|
|
434
|
-
* @brief Remove a key/value pair
|
|
435
|
-
*/
|
|
436
|
-
public int remove(String key) {
|
|
437
|
-
int index = index(key);
|
|
438
|
-
if (index != -1) {
|
|
439
|
-
removeIndex(index);
|
|
440
|
-
}
|
|
441
|
-
return index;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
public String removeIndex(int index) {
|
|
446
|
-
if (index < 0 || index >= count) {
|
|
447
|
-
throw new ArrayIndexOutOfBoundsException(index);
|
|
448
|
-
}
|
|
449
|
-
//System.out.println("index is " + which + " and " + keys[which]);
|
|
450
|
-
String key = keys[index];
|
|
451
|
-
indices.remove(key);
|
|
452
|
-
for (int i = index; i < count-1; i++) {
|
|
453
|
-
keys[i] = keys[i+1];
|
|
454
|
-
values[i] = values[i+1];
|
|
455
|
-
indices.put(keys[i], i);
|
|
456
|
-
}
|
|
457
|
-
count--;
|
|
458
|
-
keys[count] = null;
|
|
459
|
-
values[count] = null;
|
|
460
|
-
return key;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
public void swap(int a, int b) {
|
|
465
|
-
String tkey = keys[a];
|
|
466
|
-
String tvalue = values[a];
|
|
467
|
-
keys[a] = keys[b];
|
|
468
|
-
values[a] = values[b];
|
|
469
|
-
keys[b] = tkey;
|
|
470
|
-
values[b] = tvalue;
|
|
436
|
+
public void swap(int a, int b) {
|
|
437
|
+
String tkey = keys[a];
|
|
438
|
+
String tvalue = values[a];
|
|
439
|
+
keys[a] = keys[b];
|
|
440
|
+
values[a] = values[b];
|
|
441
|
+
keys[b] = tkey;
|
|
442
|
+
values[b] = tvalue;
|
|
471
443
|
|
|
472
444
|
// indices.put(keys[a], Integer.valueOf(a));
|
|
473
445
|
// indices.put(keys[b], Integer.valueOf(b));
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* Sort the keys alphabetically (ignoring case). Uses the value as a
|
|
479
|
-
* tie-breaker (only really possible with a key that has a case change).
|
|
480
|
-
*
|
|
481
|
-
* @webref stringdict:method
|
|
482
|
-
* @brief Sort the keys alphabetically
|
|
483
|
-
*/
|
|
484
|
-
public void sortKeys() {
|
|
485
|
-
sortImpl(true, false);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* @webref stringdict:method
|
|
490
|
-
* @brief Sort the keys alphabetically in reverse
|
|
491
|
-
*/
|
|
492
|
-
public void sortKeysReverse() {
|
|
493
|
-
sortImpl(true, true);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* Sort by values in descending order (largest value will be at [0]).
|
|
499
|
-
*
|
|
500
|
-
* @webref stringdict:method
|
|
501
|
-
* @brief Sort by values in ascending order
|
|
502
|
-
*/
|
|
503
|
-
public void sortValues() {
|
|
504
|
-
sortImpl(false, false);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
/**
|
|
509
|
-
* @webref stringdict:method
|
|
510
|
-
* @brief Sort by values in descending order
|
|
511
|
-
*/
|
|
512
|
-
public void sortValuesReverse() {
|
|
513
|
-
sortImpl(false, true);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
protected void sortImpl(final boolean useKeys, final boolean reverse) {
|
|
518
|
-
Sort s = new Sort() {
|
|
519
|
-
@Override
|
|
520
|
-
public int size() {
|
|
521
|
-
return count;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
@Override
|
|
525
|
-
public int compare(int a, int b) {
|
|
526
|
-
int diff = 0;
|
|
527
|
-
if (useKeys) {
|
|
528
|
-
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
529
|
-
if (diff == 0) {
|
|
530
|
-
diff = values[a].compareToIgnoreCase(values[b]);
|
|
531
|
-
}
|
|
532
|
-
} else { // sort values
|
|
533
|
-
diff = values[a].compareToIgnoreCase(values[b]);
|
|
534
|
-
if (diff == 0) {
|
|
535
|
-
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
return reverse ? -diff : diff;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
@Override
|
|
542
|
-
public void swap(int a, int b) {
|
|
543
|
-
StringDict.this.swap(a, b);
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
s.run();
|
|
547
|
-
|
|
548
|
-
// Set the indices after sort/swaps (performance fix 160411)
|
|
549
|
-
resetIndices();
|
|
550
|
-
}
|
|
551
|
-
|
|
446
|
+
}
|
|
552
447
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Sort the keys alphabetically (ignoring case). Uses the value as a
|
|
450
|
+
* tie-breaker (only really possible with a key that has a case change).
|
|
451
|
+
*
|
|
452
|
+
* @webref stringdict:method
|
|
453
|
+
* @brief Sort the keys alphabetically
|
|
454
|
+
*/
|
|
455
|
+
public void sortKeys() {
|
|
456
|
+
sortImpl(true, false);
|
|
560
457
|
}
|
|
561
|
-
outgoing.count = count;
|
|
562
|
-
return outgoing;
|
|
563
|
-
}
|
|
564
458
|
|
|
459
|
+
/**
|
|
460
|
+
* @webref stringdict:method
|
|
461
|
+
* @brief Sort the keys alphabetically in reverse
|
|
462
|
+
*/
|
|
463
|
+
public void sortKeysReverse() {
|
|
464
|
+
sortImpl(true, true);
|
|
465
|
+
}
|
|
565
466
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
467
|
+
/**
|
|
468
|
+
* Sort by values in descending order (largest value will be at [0]).
|
|
469
|
+
*
|
|
470
|
+
* @webref stringdict:method
|
|
471
|
+
* @brief Sort by values in ascending order
|
|
472
|
+
*/
|
|
473
|
+
public void sortValues() {
|
|
474
|
+
sortImpl(false, false);
|
|
569
475
|
}
|
|
570
|
-
}
|
|
571
476
|
|
|
477
|
+
/**
|
|
478
|
+
* @webref stringdict:method
|
|
479
|
+
* @brief Sort by values in descending order
|
|
480
|
+
*/
|
|
481
|
+
public void sortValuesReverse() {
|
|
482
|
+
sortImpl(false, true);
|
|
483
|
+
}
|
|
572
484
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
485
|
+
protected void sortImpl(final boolean useKeys, final boolean reverse) {
|
|
486
|
+
Sort s = new Sort() {
|
|
487
|
+
@Override
|
|
488
|
+
public int size() {
|
|
489
|
+
return count;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
@Override
|
|
493
|
+
public int compare(int a, int b) {
|
|
494
|
+
int diff = 0;
|
|
495
|
+
if (useKeys) {
|
|
496
|
+
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
497
|
+
if (diff == 0) {
|
|
498
|
+
diff = values[a].compareToIgnoreCase(values[b]);
|
|
499
|
+
}
|
|
500
|
+
} else { // sort values
|
|
501
|
+
diff = values[a].compareToIgnoreCase(values[b]);
|
|
502
|
+
if (diff == 0) {
|
|
503
|
+
diff = keys[a].compareToIgnoreCase(keys[b]);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return reverse ? -diff : diff;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
@Override
|
|
510
|
+
public void swap(int a, int b) {
|
|
511
|
+
StringDict.this.swap(a, b);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
s.run();
|
|
515
|
+
|
|
516
|
+
// Set the indices after sort/swaps (performance fix 160411)
|
|
517
|
+
resetIndices();
|
|
518
|
+
}
|
|
581
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Returns a duplicate copy of this object.
|
|
522
|
+
*/
|
|
523
|
+
public StringDict copy() {
|
|
524
|
+
StringDict outgoing = new StringDict(count);
|
|
525
|
+
System.arraycopy(keys, 0, outgoing.keys, 0, count);
|
|
526
|
+
System.arraycopy(values, 0, outgoing.values, 0, count);
|
|
527
|
+
for (int i = 0; i < count; i++) {
|
|
528
|
+
outgoing.indices.put(keys[i], i);
|
|
529
|
+
}
|
|
530
|
+
outgoing.count = count;
|
|
531
|
+
return outgoing;
|
|
532
|
+
}
|
|
582
533
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
for (int i = 0; i < count; i++) {
|
|
588
|
-
writer.println(keys[i] + "\t" + values[i]);
|
|
534
|
+
public void print() {
|
|
535
|
+
for (int i = 0; i < size(); i++) {
|
|
536
|
+
System.out.println(keys[i] + " = " + values[i]);
|
|
537
|
+
}
|
|
589
538
|
}
|
|
590
|
-
writer.flush();
|
|
591
|
-
}
|
|
592
539
|
|
|
540
|
+
/**
|
|
541
|
+
* Save tab-delimited entries to a file (TSV format, UTF-8 encoding)
|
|
542
|
+
*/
|
|
543
|
+
public void save(File file) {
|
|
544
|
+
PrintWriter writer = PApplet.createWriter(file);
|
|
545
|
+
write(writer);
|
|
546
|
+
writer.close();
|
|
547
|
+
}
|
|
593
548
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
549
|
+
/**
|
|
550
|
+
* Write tab-delimited entries to a PrintWriter
|
|
551
|
+
*/
|
|
552
|
+
public void write(PrintWriter writer) {
|
|
553
|
+
for (int i = 0; i < count; i++) {
|
|
554
|
+
writer.println(keys[i] + "\t" + values[i]);
|
|
555
|
+
}
|
|
556
|
+
writer.flush();
|
|
601
557
|
}
|
|
602
|
-
return "{ " + items.join(", ") + " }";
|
|
603
|
-
}
|
|
604
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Return this dictionary as a String in JSON format.
|
|
561
|
+
*/
|
|
562
|
+
public String toJSON() {
|
|
563
|
+
StringList items = new StringList();
|
|
564
|
+
for (int i = 0; i < count; i++) {
|
|
565
|
+
items.append(JSONObject.quote(keys[i]) + ": " + JSONObject.quote(values[i]));
|
|
566
|
+
}
|
|
567
|
+
return "{ " + items.join(", ") + " }";
|
|
568
|
+
}
|
|
605
569
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
570
|
+
@Override
|
|
571
|
+
public String toString() {
|
|
572
|
+
return getClass().getSimpleName() + " size=" + size() + " " + toJSON();
|
|
573
|
+
}
|
|
610
574
|
}
|