Showing posts with label sort. Show all posts
Showing posts with label sort. Show all posts

Thursday, July 27, 2017

Grails | Groovy | Create Criteria | Hibernate Criteria Builder | Custom Criteria Order | Custom Sort By | Custom Order Criteria

Grails | Groovy | Create Criteria | Hibernate Criteria Builder | Custom Criteria Order | Custom Sort By | Custom Order Criteria. 

In Grails we may need sometime to add sort / order by with some aggregate function as sum of two fields. Suppose we have a Grails / Groovy domain which has two field named "amount" and "tax", now we want to sort by sum of these two fields. So we can do that using below sample code: 


import groovy.lang.Closure
import org.hibernate.Criteria
import org.hibernate.HibernateException
import org.hibernate.criterion.CriteriaQuery
import org.hibernate.criterion.Order as CriterionOrder

Closure closure = {
    addOrder(new CriterionOrder("amount", params.dir) {
        @Override
        String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        return "(this_.amount + this_.tax) asc"
        }
    })
    projections {
        property("id")
        property("amount")
    }
}
List list = Domain.createCriteria().list {
    and closure
}

Saturday, December 10, 2016

PHP Sort Multidimensional array with key value


<?php
$needSort = array(
    array("name" => "Bob", "age" => 8, "colour" => "red"),
    array("name" => "Greg", "age" => 12, "colour" => "blue"),
    array("name" => "Andy", "age" => 5, "colour" => "purple")
);
echo "<h3>Original Array</h3><pre>";
print_r($needSort);
echo "</pre>";

$orderBy = "name";
$sortArray = array();
$sortArray[$orderBy] = array();

foreach ($needSort as $obj) {
    $sortArray[$orderBy][] = $obj[$orderBy]; //Sort by name
}

array_multisort($sortArray[$orderBy], SORT_ASC, $needSort);

echo "<h3>Sorted Array</h3><pre>";
print_r($needSort);
echo "</pre>";
?>

Output



Original Array

Array
(
    [0] => Array
        (
            [name] => Bob
            [age] => 8
            [colour] => red
        )

    [1] => Array
        (
            [name] => Greg
            [age] => 12
            [colour] => blue
        )

    [2] => Array
        (
            [name] => Andy
            [age] => 5
            [colour] => purple
        )

)


Sorted Array

Array
(
    [0] => Array
        (
            [name] => Andy
            [age] => 5
            [colour] => purple
        )

    [1] => Array
        (
            [name] => Bob
            [age] => 8
            [colour] => red
        )

    [2] => Array
        (
            [name] => Greg
            [age] => 12
            [colour] => blue
        )

)

Wednesday, October 30, 2013

Sort an ArrayList base on multiple attributes using java/grails

I have an ArrayList of object. The object contain attributes name and classValue. So I want to sort the objects on the classValue, and for all objects in the same classValue I want to sort them on name.


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 *
 * @author Pritom Kumar
 */
public class MapSort {
    public static void main(String[] args) {
        MapSort mapSort = new MapSort();
        mapSort.sort();
    }
    
    public void sort() {
        List keys = new ArrayList();
        HashMap map1 = new HashMap();
        map1.put("name", "Pritom");
        map1.put("classValue", 5);
        keys.add(map1);
        
        HashMap map2 = new HashMap();
        map2.put("name", "Bappi Lahiri");
        map2.put("classValue", 10);
        keys.add(map2);
        
        HashMap map3 = new HashMap();
        map3.put("name", "Ashok Kumar");
        map3.put("classValue", 5);
        keys.add(map3);

        Collections.sort(keys,
            new Comparator() {
                public int compare(Object left, Object right) {
                    HashMap leftMap = (HashMap) left;
                    HashMap rightMap = (HashMap) right;
                    Integer classValue1 = Integer.parseInt(leftMap.get("classValue").toString());
                    Integer classValue2 = Integer.parseInt(rightMap.get("classValue").toString());
                    int comp = classValue1.compareTo(classValue2);
                    return comp == 0 ? leftMap.get("name").toString().compareTo(rightMap.get("name").toString()) : comp;
                }
            });

        //List the values
        Object[] keyList = keys.toArray();
        for(Integer index = 0; index < keyList.length; index++) {
            System.out.println(keyList[index]);
        }
    }
}


And the output is as following. At first sorts by classValue and then by name.

{name=Ashok Kumar, classValue=5}
{name=Pritom, classValue=5}
{name=Bappi Lahiri, classValue=10}

Tuesday, October 8, 2013

Groovy Goodness: Sorting a List of Map by specific Key

Sorting a Map by value with Groovy is very simple, due to the added ‘sort’ method on the Map interface.
def hashMap = "fields": {
      "field_3": {
        "order": 4
      },
      "field_2": {
        "order": 3
      },
      "field_1": {
        "order": 2     
    },
      "field_0": {
        "order": 6   
      }
    }

hashMap.sort { a , b -> a.value.order <=> b.value.order }

Tuesday, April 30, 2013

CGridView a CLinkColumn with sortable header using yii

I have it working with the latest yii (non-stable but might work with the current stable release). (could do with some improvement but it does what I need)

Try this; create a new component under components/SCLinkColumnWithSort.php

<?php
class SCLinkColumnWithSort extends CLinkColumn
{

  public $name;
  public $sortable = true;
  public $filter;

  protected function renderFilterCellContent()
  {
    $this->linkHtmlOptions['class'] = $this->name;
    if($this->filter!==false && $this->grid->filter!==null && strpos($this->name,'.')===false)
    {
      if(is_array($this->filter))
        echo CHtml::activeDropDownList($this->grid->filter, $this->name, $this->filter, array('id'=>false,'prompt'=>''));
      else if($this->filter===null)
        echo CHtml::activeTextField($this->grid->filter, $this->name, array('id'=>false));
      else
        echo $this->filter;
    }
    else
      parent::renderFilterCellContent();
  }

  protected function renderHeaderCellContent()
  {
    if($this->grid->enableSorting && $this->sortable && $this->name!==null)
      echo $this->grid->dataProvider->getSort()->link($this->name,$this->header);
    else
      parent::renderHeaderCellContent();
  }

}
?> 
Use this as following: 

<?php
$this->widget('zii.widgets.grid.CGridView', array(
  'dataProvider' => $dataProvider,
  'columns' => array(
    array(
      'class' => 'SCLinkColumnWithSort',
      'name' => 'column_name_to_sort',
     )
  )
))
?> 
 
Or you can directly use, but upper one used for more customization:
array(
  'name' => 'mobile_number',
  'type' => 'raw',
  'value' => 'CHtml::link($data->mobile_number,$data->contact_id)'
) 
Where mobile_number is filed value in name, in value, mobile_number is for sorting
and contact_id is for making link.

Sunday, April 21, 2013

Sorting with Set::sort() in CakePHP 1.2

Sorting data returned from a database query

You're probably thinking "Err... idiot... just use the ORDER BY functionality in the model!". Yeah, we could do that, but that's not much fun!
Here is my freshly baked People controller, which gracefully passes some data to my view. Nothing special here.

<?php
class PeopleController extends AppController {

    var $name = 'People';
    
    function index() {
        $this->set('people', $this->Person->find('all'));
    }
    
}
?>
 
The $people array is in the standard format we receive from our model, and has a belongsTo association (Occupation).
Array
(
    [0] => Array
        (
            [Person] => Array
                (
                    [id] => 1
                    [occupation_id] => 2
                    [name] => Harry Potter
                    [birth_date] => 1980-07-31
                )

            [Occupation] => Array
                (
                    [id] => 2
                    [name] => Student
                )

        )

    [1] => Array
        (
            [Person] => Array
                (
                    [id] => 2
                    [occupation_id] => 1
                    [name] => Albus Dumbledore
                    [birth_date] => 1881-08-01
                )

            [Occupation] => Array
                (
                    [id] => 1
                    [name] => Headmaster
                )

        )

    [2] => Array
        (
            [Person] => Array
                (
                    [id] => 3
                    [occupation_id] => 3
                    [name] => Severus Snape
                    [birth_date] => 1959-01-09
                )

            [Occupation] => Array
                (
                    [id] => 3
                    [name] => Professor
                )

        )

)

Default order

Instead of dumping the entire contents of the $people array after each Set::sort() call, I will present the data in a pretty table.
Person.id Person.name Person.birth_date Occupation.id Occupation.name
1 Harry Potter 1980-07-31 2 Student
2 Albus Dumbledore 1881-08-01 1 Headmaster
3 Severus Snape 1959-01-09 3 Professor

Person.birth_date DESC

Set::sort() currently takes 3 arguments - the array to sort, the array value to sort on, and the sort order. As with the other Set methods, we specify the value to sort on using a key path. This makes it super easy to deal with complex arrays.

$people = Set::sort($people, '{n}.Person.birth_date', 'desc');
 

Person.id Person.name Person.birth_date Occupation.id Occupation.name
1 Harry Potter 1980-07-31 2 Student
3 Severus Snape 1959-01-09 3 Professor
2 Albus Dumbledore 1881-08-01 1 Headmaster

Occupation.name ASC

It's just as simple sorting on a value of an associated model, in this case the person's occupation. Unfortunately the sort method doesn't current have a default sort order, so we need to specify this. We can also use the PHP constants, SORT_ASC and SORT_DESC.

$people = Set::sort($people, '{n}.Occupation.name', SORT_ASC);
 

Person.id Person.name Person.birth_date Occupation.id Occupation.name
2 Albus Dumbledore 1881-08-01 1 Headmaster
3 Severus Snape 1959-01-09 3 Professor
1 Harry Potter 1980-07-31 2 Student