我试图找出基于匹配逻辑和输入搜索条件显示组合表的最佳方法。
情况如下:
我们有一个本地存储的客户表。感兴趣的字段是ssn,名字,姓氏和出生日期。
我们还有一个提供相同信息的Web服务。 Web服务的某些客户与本地文件相同,但有些不同。
两者均不需要SSN。
我需要合并这些数据以便在Grails显示器上进行查看。
组合的标准是1)在SSN上匹配。 2)对于任何剩余记录,名字,姓氏和出生日期应完全匹配。
此时无需Soundex或近似逻辑。
看来我应该从两个输入中提取所有记录到单个集合中,以某种方式将其设置为SSN。然后删除空白的ssn。
这将处理SSN匹配(一旦我弄清楚如何进行设置)。
然后,我需要回到原始的两个输入源(缓存在集合中以防止重新读取),并删除先前派生的SSN集中存在的所有记录。
然后,根据名字,姓氏和出生日期创建另一组-如果我能弄清楚如何制作一组,请再次创建。
然后将两个派生的集合合并为一个集合。出于显示目的,应该对集合进行排序。
这有意义吗?我认为搜索条件将限制提取的记录数,因此我可以在内存中执行此操作。
本质上,我正在寻找一些有关Grails代码如何实现上述逻辑的想法(假设这是一种好方法)。本地客户表是一个域对象,而我从WS获得的是对象的数组列表。
另外,我不清楚用于显示的maxresults,firstResult和顺序如何受到影响。我想我需要首先读取所有符合搜索条件的记录,进行合并,并从派生的集合中进行显示。
最佳答案
传统的Java方法是使用自定义比较器将本地和远程对象都复制到TreeSet容器中,第一个用于SSN,第二个用于名称/生日。
这可能看起来像:
def localCustomers = Customer.list()
def remoteCustomers = RemoteService.get()
TreeSet ssnFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.ssn <=> c2.ssn}))
ssnFilter.addAll(localCustomers)
ssnFilter.addAll(remoteCustomers)
TreeSet nameDobFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.firstName + c1.lastName + c1.dob <=> c2.firstName + c2.lastName + c2.dob}))
nameDobFilter.addAll(ssnFilter)
def filteredCustomers = nameDobFilter as List
此时,filteredCustomers拥有所有记录,但那些记录被您的两个条件重复的除外。
另一种方法是通过排序和执行foldr操作来过滤列表,并在相邻元素匹配时组合它们。这样,您就有机会合并来自两个来源的数据。
例如:
def combineByNameAndDob(customers) {
customers.sort() {
c1, c2 -> (c1.firstName + c1.lastName + c1.dob) <=>
(c2.firstName + c2.lastName + c2.dob)
}.inject([]) { cs, c ->
if (cs && c.equalsByNameAndDob(cs[-1])) {
cs[-1].combine(c) //combine the attributes of both records
cs
} else {
cs << c
}
}
}
关于grails - 在Grails中合并表格,Web服务数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2372203/