遍历/修改Groovy数据结构
问题描述:
我正在开发一个项目,该项目将以专有格式读取某些数据,将其收集到一个统一的Groovy数据结构中,并将其写入一个整洁的XML(或JSON,还没有决定)格式。 我是Groovy的新手,但是,该项目是Ant构建项目,Groovy似乎是最好的选择。遍历/修改Groovy数据结构
到目前为止,我能够读取数据,创建原子结构,使用>>操作符连接它们,并使用MarkupBuilder将它们无缝地转储到XML(比在Java中执行操作更简单)。但是,我现在被困在了需要稍微修改聚集结构或者遍历它们来组成一些聚合数据的时候。
为了举例说明,假设我们收集了我们的数据,所以它等同于:
def inventory = {
car (make: "Subaru", model: "Impreza WRX", year: 2010, color: "Blue") {
feature ("Premium sound")
feature ("Brembo brakes")
bug ("Leaks oil")
bug ("Needs new transmission")
}
car (make: "Jeep", model: "Wrangler", year: 13, awd: true) {
feature ("Soft top")
bug ("Doesn't start")
bug ("Flooded")
}
// blahblahblah
}
,我们正在努力实现以下,例如:
- 删除所有“错误”的项目(假设,我们正在撰写一份在经销商网站上发布的清单)。或者,所有“功能”(如果是我们的售前维修班)。
- 浏览清单,并确保所有的“年”的属性是4位数
- 过时的所有“AWD”的属性,移动他们的“功能”列表
所以我们最终有如下的结构这样的:
def inventory = {
car (make: "Subaru", model: "Impreza WRX", year: 2010, color: "Blue") {
feature ("Premium sound")
feature ("Brembo brakes")
}
car (make: "Jeep", model: "Wrangler", year: 2013) {
feature ("AWD")
feature ("Soft top")
}
// blahblahblah
}
其实,我是通过原来的结构组成一个新的列表吧(我的数据是不是巨大的,要求就地编辑)OK,但我怎么通过这个结构遍历,首先?
哦,还有一个术语问题。也许,我只是在搜索一个错误的关键字......这个代码中定义的实体:它也被称为“关闭”,或者有一个不同的术语?
答
看着inventory
,它实际上是由一些这样表示
@Immutable(copyWith = true)
class Car {
String make
String model
int year
String color
boolean awd
List<String> features
List<String> bugs
}
当你的罚款与构成一个新的列表(也有一般来讲几个理由不这样做),你可以添加@Immutable
注释。作为“副作用”,您可以添加copyWith = true
以获取复制方法。
的inventory
的定义看起来是这样的:
def inventory = [
new Car(
make: "Subaru",
model: "Impreza WRX",
year: 2010,
color: "Blue",
features: ["Premium sound", "Brembo brakes"],
bugs: ["Leaks oil", "Needs new transmission"]),
new Car(
make: "Jeep",
model: "Wrangler",
year: 13,
awd: true,
features: ["Soft top"],
bugs: ["Doesn't start", "Flooded"])
]
,让你的数据的不可变represenation。 然后,您可以使用收集API遍历和更改数据。在你的情况:
def result = inventory
.collect { it.copyWith(bugs: []) }
.collect { it.copyWith(year:
it.year < 2000 ? it.year + 2000 : it.year) }
.collect {
if (it.awd) {
it.copyWith(features: it.features + "AWD")
} else {
it
}
每个转换单独应用(并且只有不变的实例流经该管道)。
如果你真的要删除空的错误列表和/或awd
属性,定义目标类:
class FixedCar {
String make
String model
int year
String color
List<String> features
static FixedCar apply(Car car) {
new FixedCar(
make: car.make,
model: car.model,
year: car.year,
color: car.color,
features: car.features)
}
}
和另一个呼叫添加到collect
:
def result = inventory
.collect { it.copyWith(bugs: []) }
.collect { it.copyWith(year:
it.year < 2000 ? it.year + 2000 : it.year) }
.collect {
if (it.awd) {
it.copyWith(features: it.features + "AWD")
} else {
it
}
}.collect { FixedCar.apply(it) }
由于groovy中的代码是无数据的,因此您必须在DSL之前或之后进行转换。到目前为止还不是很清楚,这是如何将所有链接起来,并在中间代表你的上面的groovy代码实际上是。有人在写它,你只是在一个标记生成器中运行它? – cfrick