Groovy,在当前节点后插入节点
Groovy, insert node after current node
我会尽力解释情况。
我有以下数据库列:
oid - task - start - end - realstart - realend
我的要求是输出如下:
oid1 - task1 - start1 - end1
oid2 - task2 - start2 - end2
其中task1是task
,task2是task + "real"
,start1是start
,start2是realstart
,end1是end
,end2是realend
但是
应该始终创建第一行(那些 start/end
字段永远不会为空)第二行应该仅在 realstart
和 realend
存在时创建,这可能不是真的。
输入是 6 个数组(每列一个),输出必须是 4 个数组,如下所示:
#input oid,task,start,end,realstart,realend
#output oid,task,start,end
我正在考虑使用 oid.each
之类的东西,但我不知道如何在当前节点之后添加节点。订单在需求中很重要。
如有任何解释,请询问,谢谢!
如果您需要一个 "array",但您从一开始就不知道其大小,您应该改用 List
。但是在 Groovy 中,这非常容易使用。
这是一个例子:
final int OID = 0
final int TASK = 1
final int START = 2
final int END = 3
final int R_START = 4
final int R_END = 5
List<Object[]> input = [
//oid, task, start, end, realstart, realend
[ 'oid1', 'task1', 10, 20, 12, 21 ],
[ 'oid2', 'task2', 30, 42, null, null ]
]
List<List> output = [ ]
input.each { row ->
output << [ row[ OID ], row[ TASK ], row[ START ], row[ END ] ]
if ( row[ R_START ] && row[ R_END ] ) {
output << [ row[ OID ], row[ TASK ] + 'real', row[ R_START ], row[ R_END ] ]
}
}
println output
输出:
[[oid1, task1, 10, 20], [oid1, task1real, 12, 21], [oid2, task2, 30, 42]]
在您发表评论并了解您不想(或不能)更改 input/output 数据格式后,这是另一个解决方案,可以使用 classes 对数据进行分组数据并使其更易于管理:
import groovy.transform.Canonical
@Canonical
class Input {
String[] oids = [ 'oid1', 'oid2' ]
String[] tasks = [ 'task1', 'task2' ]
Integer[] starts = [ 10, 30 ]
Integer[] ends = [ 20, 42 ]
Integer[] realstarts = [ 12, null ]
Integer[] realends = [ 21, null ]
List<Object[]> getEntries() {
// ensure all entries have the same size
def entries = [ oids, tasks, starts, ends, realstarts, realends ]
assert entries.collect { it.size() }.unique().size() == 1,
'The input arrays do not all have the same size'
return entries
}
int getSize() {
oids.size() // any field would do, they have the same length
}
}
@Canonical
class Output {
List oids = [ ]
List tasks = [ ]
List starts = [ ]
List ends = [ ]
void add( oid, task, start, end, realstart, realend ) {
oids << oid; tasks << task; starts << start; ends << end
if ( realstart != null && realend != null ) {
oids << oid; tasks << task + 'real'; starts << realstart; ends << realend
}
}
}
def input = new Input()
def entries = input.entries
def output = new Output()
for ( int i = 0; i < input.size; i++ ) {
def entry = entries.collect { it[ i ] }
output.add( *entry )
}
println output
整理数据的责任在Input
class,而知道如何组织输出数据的责任在Output
class。
运行 此代码打印:
Output([oid1, oid1, oid2], [task1, task1real, task2], [10, 12, 30], [20, 21, 42])
您可以使用 output.oids
、[=17= 从 output
对象中获取数组(实际上是列表,但如果在列表上则调用 toArray()
获取数组) ]、output.starts
和 output.ends
.
@Canonical
注解只是让class实现equals、hashCode、toString等等...
有什么不明白的可以在评论里提问。
我会尽力解释情况。
我有以下数据库列:
oid - task - start - end - realstart - realend
我的要求是输出如下:
oid1 - task1 - start1 - end1
oid2 - task2 - start2 - end2
其中task1是task
,task2是task + "real"
,start1是start
,start2是realstart
,end1是end
,end2是realend
但是
应该始终创建第一行(那些 start/end
字段永远不会为空)第二行应该仅在 realstart
和 realend
存在时创建,这可能不是真的。
输入是 6 个数组(每列一个),输出必须是 4 个数组,如下所示:
#input oid,task,start,end,realstart,realend
#output oid,task,start,end
我正在考虑使用 oid.each
之类的东西,但我不知道如何在当前节点之后添加节点。订单在需求中很重要。
如有任何解释,请询问,谢谢!
如果您需要一个 "array",但您从一开始就不知道其大小,您应该改用 List
。但是在 Groovy 中,这非常容易使用。
这是一个例子:
final int OID = 0
final int TASK = 1
final int START = 2
final int END = 3
final int R_START = 4
final int R_END = 5
List<Object[]> input = [
//oid, task, start, end, realstart, realend
[ 'oid1', 'task1', 10, 20, 12, 21 ],
[ 'oid2', 'task2', 30, 42, null, null ]
]
List<List> output = [ ]
input.each { row ->
output << [ row[ OID ], row[ TASK ], row[ START ], row[ END ] ]
if ( row[ R_START ] && row[ R_END ] ) {
output << [ row[ OID ], row[ TASK ] + 'real', row[ R_START ], row[ R_END ] ]
}
}
println output
输出:
[[oid1, task1, 10, 20], [oid1, task1real, 12, 21], [oid2, task2, 30, 42]]
在您发表评论并了解您不想(或不能)更改 input/output 数据格式后,这是另一个解决方案,可以使用 classes 对数据进行分组数据并使其更易于管理:
import groovy.transform.Canonical
@Canonical
class Input {
String[] oids = [ 'oid1', 'oid2' ]
String[] tasks = [ 'task1', 'task2' ]
Integer[] starts = [ 10, 30 ]
Integer[] ends = [ 20, 42 ]
Integer[] realstarts = [ 12, null ]
Integer[] realends = [ 21, null ]
List<Object[]> getEntries() {
// ensure all entries have the same size
def entries = [ oids, tasks, starts, ends, realstarts, realends ]
assert entries.collect { it.size() }.unique().size() == 1,
'The input arrays do not all have the same size'
return entries
}
int getSize() {
oids.size() // any field would do, they have the same length
}
}
@Canonical
class Output {
List oids = [ ]
List tasks = [ ]
List starts = [ ]
List ends = [ ]
void add( oid, task, start, end, realstart, realend ) {
oids << oid; tasks << task; starts << start; ends << end
if ( realstart != null && realend != null ) {
oids << oid; tasks << task + 'real'; starts << realstart; ends << realend
}
}
}
def input = new Input()
def entries = input.entries
def output = new Output()
for ( int i = 0; i < input.size; i++ ) {
def entry = entries.collect { it[ i ] }
output.add( *entry )
}
println output
整理数据的责任在Input
class,而知道如何组织输出数据的责任在Output
class。
运行 此代码打印:
Output([oid1, oid1, oid2], [task1, task1real, task2], [10, 12, 30], [20, 21, 42])
您可以使用 output.oids
、[=17= 从 output
对象中获取数组(实际上是列表,但如果在列表上则调用 toArray()
获取数组) ]、output.starts
和 output.ends
.
@Canonical
注解只是让class实现equals、hashCode、toString等等...
有什么不明白的可以在评论里提问。