EN · DE · RU · FR · ES

#354: GeneralAggregation.groovy

projectforge-business/src/main/groovy/GeneralAggregation.groovy Tipo: Groovy · Rol: Componente · Fuente: projectforge-business/src/main/groovy/GeneralAggregation.groovy 111 líneas · 64 código · 19 comentarios · 28 en blanco
Archivo de código fuente en projectforge-business/src/main/groovy/GeneralAggregation.groovy que contiene código Groovy para la capa de Componente.

Estructura del código

Clases: GeneralAggregation

Código fuente (resumido)

class GeneralAggregation {
	
	public static void main(def args){
	
		// Equivalente, si ...
		Closure equiv = {l1, l2 -> l1[0] % 5 == l2[0] % 5}
	
		// Media aritmética de la 4.ª y desviación estándar de la 5.ª columna (la indexación de columnas comienza en 0)
		Closure init = {l -> 	l[3]=[1,l[3]]
								l[4]=[1,l[4]**2]
								l}
		
		Closure agg = {l,a -> 	a[3]=[a[3][0]+=1,a[3][1]+=l[3]]
								a[4]=[a[4][0]+=1,a[4][1]+=l[4]**2]}
		
		Closure fin = {a ->		a[3] = a[3][1]/a[3][0]
								a[4] = (a[4][1]/a[4][0])**0.5}
		
		Closure iaf = {i -> def aggfun = [init,agg,fin]
							return [i]}
		
		// Datos de ejemplo: tenga en cuenta que la tercera entrada debe ser constante en la clase de equivalencia
		List list = (0..100).collect{n -> [n,2*n,n % 2,n,n]}

		aggregate2(list,equiv,init,agg,fin).each{println it}
		
		def lol = (1..10).collect{n -> (1..3).collect{m -> n*m}}
		//println lolToLoo(lol,["first","second","third"]).each{o -> println o.first+" "+o.second+" "+o.third}
		
		
		// Alternativa con HashMap
		List mlist = (0..100).collect{n -> 	def m = new HashMap()
										 	m['first'] = n
										 	m['second'] = 2*n
										 	m['third'] = n % 2
										 	m['fourth'] = n
										 	m['fifth'] = n
										 	return m}
		
		Closure equiv2 = {l1, l2 -> l1.first % 5 == l2.first % 5}

		Closure init2 = {l -> 	l.fourth=[1,l.fourth]
								l.fifth=[1,l.fifth**2]
								l}

		Closure agg2 = {l,a -> 	a.fourth=[a.fourth[0]+=1,a.fourth[1]+=l.fourth]
								a.fifth=[a.fifth[0]+=1,a.fifth[1]+=l.fifth**2]}
		
		Closure fin2 = {a ->	a.fourth = a.fourth[1]/a.fourth[0]
								a.fifth = (a.fifth[1]/a.fifth[0])**0.5}
		
		aggregate(mlist,equiv2,init2,agg2,fin2).each{println it}
		
	}
	
	/*
	 * lol es una lista de listas que representa la tabla (cada elemento es una lista que describe una fila de la tabla)
	 * equiv es una relación de equivalencia en n columnas de la lista
	 * init es un closure que describe la inicialización de la función de agregación
	 * agg es un closure que describe la agregación de la función de agregación
	 * finalize es un closure que describe la finalización de la función de agregación
	 */
	public static List aggregate2(List<List> lol, Closure equiv, Closure init = {x -> x}, Closure agg, Closure finalize = {x -> x}) {
		def resultTable = [] // Tabla con valores agregados
		def rep = [] // Fila en resultTable con representante de la clase de equivalencia y agregado

		lol.each{ row ->
			if((rep = resultTable.find{r -> equiv(row,r)}) != null) agg(row,rep)
			else resultTable << init(row)
		}
		
		resultTable.each{finalize(it)}
	}
	
  /*
   * Closure para generar relación de equivalencia para agregación
   */
	public static Closure createEquiv(List<String> fields) {
    def getter = HashMap.class.getMethod("get",Object)
		return {x,y ->  fields.inject(true) {cumPropValue, field -> cumPropValue && getter.invoke(x,field) == getter.invoke(y,field)}}
	}
	
	/*
	 * lom es una lista de Mapas
	 */
	
	public static List aggregate(List<HashMap> lom, Closure equiv, Closure init = {x -> x}, Closure agg, Closure finalize = {x -> x}) {
		def resultTable = [] // Tabla con valores agregados
		def rep = [] // Fila en resultTable con representante de la clase de equivalencia y agregado
	
		lom.each{row ->
			if((rep = resultTable.find{r -> equiv(row,r)}) != null) agg(row,rep)
			else resultTable << init(row)
		}
		
		resultTable.each{finalize(it)}
	}
	
	// Transforma objeto y lista de atributos (strings) en lista de valores de los atributos
	public static List looToLol(List loo, List attlist) {
		Closure o2l = {obj,attList -> attList.collect{att -> obj."${att}"}}
		loo.collect{obj -> o2l(obj,attList)}
	}
	
	public static List lolToLoo(List lol, List attnames) {
		return lol.collect{list -> def x = new Expando()
							(0..(attnames.size-1)).each{n -> x."${attnames[n]}" = list[n]}
							return x}
	}
	
}

Historial de Git

9ebb88522 Commit inicial