-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathgroupby.java
More file actions
138 lines (118 loc) · 4.36 KB
/
groupby.java
File metadata and controls
138 lines (118 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Copyright (c) Jython Developers */
package org.python.modules.itertools;
import org.python.core.ArgParser;
import org.python.core.Py;
import org.python.core.PyIterator;
import org.python.core.PyObject;
import org.python.core.PyTuple;
import org.python.core.PyType;
import org.python.core.PyXRange;
import org.python.core.Visitproc;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
@ExposedType(name = "itertools.groupby", base = PyObject.class, doc = groupby.groupby_doc)
public class groupby extends PyIterator {
public static final PyType TYPE = PyType.fromClass(groupby.class);
private PyIterator iter;
public groupby() {
super();
}
public groupby(PyType subType) {
super(subType);
}
public groupby(PyObject iterable) {
super();
groupby___init__(iterable, Py.None);
}
public groupby(PyObject iterable, PyObject keyfunc) {
super();
groupby___init__(iterable, keyfunc);
}
public static final String groupby_doc =
"groupby(iterable[, keyfunc]) -> create an iterator which returns\n" +
"(key, sub-iterator) grouped by each value of key(value).";
/**
* Creates an iterator that returns the items of the iterable for which
* <code>predicate(item)</code> is <code>true</code>. If <code>predicate</code> is null
* (None) return the items that are true.
*/
@ExposedNew
@ExposedMethod
final void groupby___init__(PyObject[] args, String[] kwds) {
ArgParser ap = new ArgParser("groupby", args, kwds, "iterable", "key");
if(args.length > 2){
throw Py.TypeError("groupby takes two arguments, iterable and key");
}
PyObject iterable = ap.getPyObject(0);
PyObject keyfunc = ap.getPyObject(1, Py.None);
groupby___init__(iterable, keyfunc);
}
private void groupby___init__(final PyObject iterable, final PyObject keyfunc) {
iter = new itertools.ItertoolsIterator() {
PyObject currentKey;
PyObject currentValue;
PyObject iterator = iterable.__iter__();
PyObject targetKey = currentKey = currentValue = new PyXRange(0);
public PyObject __iternext__() {
while (currentKey.equals(targetKey)) {
currentValue = nextElement(iterator);
if (currentValue == null) {
return null;
}
if (keyfunc == Py.None) {
currentKey = currentValue;
} else {
currentKey = keyfunc.__call__(currentValue);
}
}
targetKey = currentKey;
return new PyTuple(currentKey, new GroupByIterator());
}
class GroupByIterator extends itertools.ItertoolsIterator {
private boolean completed = false;
public PyObject __iternext__() {
final PyObject item = currentValue;
if (completed) {
return null;
}
currentValue = nextElement(iterator);
if (currentValue == null) {
completed = true;
} else {
if (keyfunc == Py.None) {
currentKey = currentValue;
} else {
currentKey = keyfunc.__call__(currentValue);
}
}
if (!currentKey.equals(targetKey)) {
completed = true;
}
return item;
}
}
};
}
public PyObject __iternext__() {
return iter.__iternext__();
}
@ExposedMethod
@Override
public PyObject next() {
return doNext(__iternext__());
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal = super.traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
return iter != null ? visit.visit(iter, arg) : 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (iter == ob || super.refersDirectlyTo(ob));
}
}