• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Implementing a pivot table / cross table
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Implementing a pivot table / cross table


  • Subject: Re: Implementing a pivot table / cross table
  • From: Jean-François Veillette <email@hidden>
  • Date: Fri, 17 Mar 2006 12:48:44 -0500


Le 06-03-17, à 11:45, Rico Landefeld a écrit :


In your case, I do not know you model enough to indicate if a key-path can be found from 'Failure' that will be used to segment it from one bucket from the other. I guess 'Failure' to 'FailureAttribute' is a to-many relationship. If you want to segment 'Failures' based on some sort of elements inside that relationship, either add a method in 'Failure'

no, there are to-one relationships to the four "failure attribute" entities. i can't use keypaths because the entities "origin", "outcome", "occurence" and "cause" are hierarchical (recursive to-n relations, 4 levels). a possible questions is "how many failures occured with outcome site->splices->wu-splices->leaky and origin extern->subcontractors->companyxy".

In this situation, the 2 dimensions would be : 1- "site.splices.wu-splices" 2- "extern.subcontractors"

you would get a matrix based on those 2 dimensions. You then ask the coordinate for {"site.splices.wu-splices":"leaky", "extern.subcontractors":"companyxy"} and you would get the population for that bucket. From there you just get the 'count'.


the "->" marks the level to sublevel step.

I'm not sure I understand your model.
Are you talking about class hierarchies (class superclass kind of things) or object graph (object-A --toOne--> objectB --toOne--> objectC ).



i need only one or two dimensional crosstables. but the dimensions should be free configurable (which failure attribute and level). the problem is that for an "origin" subcontractor at level 2, i have to count the failures which are directly linked with subcontractor and all failures which are linked with elements in the subcontractor subtree.

Whatever it is. You need to define the dimension / segmentation path.
From what I understand, it seem that it's hard to define the dimension due to the deept of the object graph and the fact that requests are add-hoc from end-users.


thank you four your class. but its hard to read for me, i don't speak any french ;-). but i hope i'll figure out the basic ideas.

Here is a quick/dirty translation (not tested):
package org.champlain.tamia;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Enumeration;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSKeyValueCodingAdditions;

/**
 * The <code>Grouper</code> class take care of grouping a population of objects based on one or multiples attributes.
 *
 * @version	$Revision$, $Date$
 * <br>&copy; 2005 Jean-Franois Veillette.
 */
public class Grouper  {

	static GroupDelegate basisDelegate = new GroupDefaultDelegate();

	public Grouper() {
		super();
	}

	/** Utility method to get groups based on one key. */
	public HashMap groupPopulationOnKeyPath(NSArray a, String kp, GroupDelegate delegue) {
		return groupObjectFromPopulationKeyPath(a, new String[]{kp}, delegue);
	}

	/** Utility method to get groups based on multiple keys. */
	public HashMap groupObjectFromPopulationKeyPath(NSArray a, String[] clefs, Delegue delegue) {
		HashSet clefSet = (HashSet)new HashSet(java.util.Arrays.asList(clefs));
		return groupPopulation(a, clefs, delegue);
	}

	/** Method to regroup based on 'n' keys. ('n' dimension matrix) */
	public HashMap groupPopulation(NSArray population, String[] keys, GroupDelegate delegue) {
		if(delegue == null) {
			delegue = delegueDeBase;
		}
		HashMap synthese = new HashMap();
		Enumeration enu = population.objectEnumerator();
		while(enu.hasMoreElements()) {
			NSKeyValueCodingAdditions item = (NSKeyValueCodingAdditions)enu.nextElement();
			// gŽnre la clŽ d'identification de la cellule
			HashSet clefSet = new HashSet();
			NSMutableArray l = new NSMutableArray();
			for(int i = 0 ; i < clefs.length ; i++ ) {
				String cl = clefs[i];
				Object model = delegue.groupValueForKey(item, cl);
				KeyValue cv = new KeyValue(cl, model);
				l.addObject(cv);
				// ajoute a la liste des clefs possible par groupements
				HashSet listeParGroupe = (HashSet)synthese.get(cl);
				if(listeParGroupe == null) {
					listeParGroupe = new HashSet();
					synthese.put(cl, listeParGroupe);
				}
				listeParGroupe.add(cv);
			}
			addToBuckets(synthese, l, item);
		}
		return synthese;
	}

	/** Ajoute l'objet 'obj' dans tout les 'bucket' crŽŽ par chacune des combinaisons de clef possible dans 'attributs' */
	void addToBuckets(HashMap synthese, NSArray attributs, Object obj) {
		// pour chacune des combinaisons de clef, on prend le 'bucket' et on ajoute ˆ sa population
		Enumeration attEnum = attributs.objectEnumerator();
		NSMutableArray clefGenere = new NSMutableArray();
		while(attEnum.hasMoreElements()) {
			// on gŽnre les combinaisons
			KeyValue cv = (KeyValue)attEnum.nextElement();
			Enumeration clefEnum = clefGenere.objectEnumerator();
			while(clefEnum.hasMoreElements()) {
				HashSet clefs = (HashSet)clefEnum.nextElement();
				HashSet nc = (HashSet)clefs.clone();
				nc.add(cv);
				addToBucket(synthese, nc, obj);
			}
			HashSet b = new HashSet();
			b.add(cv);
			addToBucket(synthese, b, obj);
			clefGenere.addObject(b);
		}
	}

	/** Ajoute l'objet 'obj' dans la liste associŽ au 'bucket'. */
	void addToBucket(HashMap synthese, HashSet bucket, Object obj) {
		NSMutableArray b = (NSMutableArray)synthese.get(bucket);
		if(b == null) {
			b = new NSMutableArray();
			synthese.put(bucket, b);
		}
		b.addObject(obj);
	}

	/** Object used to represent a key element on the group result set.  */
	public static class KeyValue {
		public String clef;
		public Object valeur;

		public KeyValue(String c, Object v) {
			super();
			clef = c;
			valeur = v;
		}
		public int hashCode() {
			int vh = valeur == null ? 0 : valeur.hashCode();
			int ch = clef == null ? 0 : clef.hashCode();
			return ch + vh;
		}
		public boolean equals(Object b) {
			if (b instanceof KeyValue) {
				KeyValue bb = (KeyValue)b;
				return ((clef == null) || (bb == null) || (valeur == null) ) || clef.equals(bb.clef) && valeur.equals(bb.valeur);
			}
			return false;
		}
		public String toString() {
		return "<KeyValue clef="+clef+" valeur="+valeur+" hashCode="+hashCode()+" />";
		}
	}

/** A delegate can be used to get different group values from a fiven key.  The default implementation just use NSKeyValueCoding protocol.   For example, to customize values returnes from an object to group together some values (age group like [0-6], [7-13], [14-18], [29-35], ...), the delegate could return the corresponding group value (let's say a string like "[7-13]") when asked for a given key.  */
	static public interface GroupDelegate {
		public Object groupValueForKey(Object objet, String clef);
	}

	static public class GroupDefaultDelegate implements Delegue {
		public Object groupValueForKey(Object objet, String clef) {
			return NSKeyValueCodingAdditions.DefaultImplementation.valueForKeyPath(objet, clef);
		}
	}
}


- jfv
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Lighttpd
      • From: thibault <email@hidden>
References: 
 >Implementing a pivot table / cross table (From: Rico Landefeld <email@hidden>)
 >Re: Implementing a pivot table / cross table (From: Jean-François Veillette <email@hidden>)
 >Re: Implementing a pivot table / cross table (From: Rico Landefeld <email@hidden>)
 >Re: Implementing a pivot table / cross table (From: Jean-François Veillette <email@hidden>)
 >Re: Implementing a pivot table / cross table (From: Rico Landefeld <email@hidden>)

  • Prev by Date: Re: Tales from the Dark Side
  • Next by Date: Lighttpd
  • Previous by thread: Re: Implementing a pivot table / cross table
  • Next by thread: Lighttpd
  • Index(es):
    • Date
    • Thread