úterý 15. května 2012

Metoda inject() v Groovy

Včera jsem po přečtení článku narazil znovu na fci inject(). Tuto fci jsem předtím moc nechápal, tak jsem se rozhodl, že ho zkusím použít v aplikaci, kterou zrovna dělám.

Příklad:
Chci v jqGrid použít dropwdown menu pro filtrování položek. Abych udělal toto dropdown menu, potřebuji dostat řetězec vypadající asi takto:
:Vše;NEW:Nová;SENT:Odeslaná;CLOSED:Uzavřená
kde mám vždy dvojici hodnotu option value a text, který se zobrazuje. Obě tyto hodnoty můžu získat z enumerační třídy.

enum Status {
        NEW("Nová"),
        SENT("Odeslaná"),
        CLOSED("Uzavřená")
        String czech
        Status(String czech) {
            this.czech = czech
        }
    }
Jeden způsob, jakým mohu získat předchozí řetězec, je tento:
var statusEnumsStr = "${protetika.Invoice.Status.values().collect { it.name() + ":" + it.czech}.join(";")}";
statusEnumsStr = ":Vše;"+ statusEnumsStr; 
Metoda values() vrací Collection<Status> se všemi enum hodnoty, který pak přeměním na řetězec složený z jména hodnoty (metoda name()) a českého názvu hodnoty, a "posbírám" tyto řetězce (metoda collect()) do nové kolekce. Hodnoty z této kolekce pak spojím do jednoho řetězce pomocí ";". Teď už mám řetězec:
NEW:Nová;SENT:Odeslaná;CLOSED:Uzavřená
Zbytek je jasné.

Teď to samé udělám pomocí metody inject():
var statusEnumsStr = "${protetika.Invoice.Status.values().inject(":Vše") {initVal, colVal -> initVal + ";" + colVal.name() + ":" + colVal.czech }}";
Metoda inject bere 2 parametry: inicializační parametr a closure. Funguje tak, že pro první prvek v kolekci provede to, co je v closure, a výsledek se pak stane inicializační hodnotou pro další prvek. Lepší znázornění:

  1. naše kolekce [name: "NEW", czech:"Nová"; name: "SENT", czech: "Odeslaná"; name: "CLOSED", czech: "Uzavřená"]
  2. inicializační hodnota je ":Vše" a první prvek v kolekci je name: "NEW", czech:"Nová"
  3. V closure se provede ":Vše" + ";" + "NEW" + ":" + "Nová" a tato hodnota se vrací jako další inicializační hodnota
  4. Pro druhý prvek kolekce name: "SENT", czech: "Odeslaná" je pak k dispozici inic. hodnota :Vše;NEW:Nová;

Kroky se pak opakují.

Žádné komentáře:

Okomentovat