MultiSort

public domain. no guarentees, use it as you wish.
author: kobi
the needed functions follow.

purpose: sorts a list of objects based on multiple criteria, the criteria are "fields" in the object (cells in the sequence)

It was simple to produce thanks to the built in custom_sort.
the passed 'fields' argument is assumed to be a normal enum (starts from 1), for accessing the field index.

 
-- multi_sort.e 
namespace multi_sort  
  
include assert.e  
include std/sort.e  
include conditions.e  
  
function compare_two(sequence a, sequence b, sequence fields)  
    require(all_positive(fields),"fields must be positive")  
    for i=1 to length(fields) do  
        integer field = fields[i]  
        integer cmp = compare(a[field],b[field])  
        if cmp != 0 then  
            return cmp  
        end if 
    end for  
    return 0 -- equal.  
end function  
  
public function multisort(sequence seq, sequence fields_order)  
     return custom_sort(routine_id("compare_two"), seq, {fields_order}) 
end function  
-- assert.e 
namespace assert   
   
include std/error.e   
  
public procedure assert(integer x, sequence text = "")   
	if x = 0 then   
		crash(text)   
	end if   
end procedure   
  
public procedure require(integer x,sequence text="")  
    assert(x,text)  
end procedure  
-- conditions.e  
namespace conditions  
include seq_ops.e   
  
function positive(atom a)  
    return a > 0  
end function  
  
public function all_positive(sequence sequ)  
    integer rid = routine_id("positive")  
    return all(sequ,rid)  
end function  
 
function notneg(atom a)  
    return not (a < 0)  
end function  
  
public function all_uint(sequence sequ)  
    integer rid = routine_id("notneg")  
    return all(sequ,rid)  
end function  
  
-- seq_ops.e  
include assert.e  
  
public function all(sequence seq, integer func)  
    for i=1 to length(seq) do  
        if call_func(func,{seq[i]}) = 0 then  
            return 0  
        end if  
    end for  
      
    return 1  
end function  
 
 

Example and unit tests:

-- t_multi_sort.ex 
include std/unittest.e 
include multi_sort.e 
include conditions.e 
 
type house(sequence seq)  
    return length(seq)=4 and all_uint(seq)  
end type  
  
enum CHAIR, DESK, ROOMS, WALL  
--                CHAIR, DESK, ROOMS, WALL  
house a =   {3,          4,        2,            1}  
house b =   {4,          1,        2,            2}  
house c =   {5,          4,        3,            1}  
house d =   {3,          4,        2,            3}  
  
test_equal("multi sort 1",   
 {  
   {3,4,2,1},  
   {5,4,3,1},  
   {4,1,2,2},  
   {3,4,2,3}  
 } 
, 
multisort({a,b,c,d}, { WALL, ROOMS, DESK, CHAIR})) 
--  
 
test_equal("multi sort 2",   
 {  
   {4,1,2,2},  
   {3,4,2,1},  
   {3,4,2,3}, 
   {5,4,3,1}  
 } 
, 
multisort({a,b,c,d}, { ROOMS,DESK, CHAIR})) 
-- 
 
 
test_equal("multi sort 3",   
 {  
   {3,4,2,1}, 
   {3,4,2,3}, 
   {4,1,2,2},  
   {5,4,3,1} 
 } 
, 
multisort({a,b,c,d}, { CHAIR, DESK, ROOMS, WALL})) 
 

Search



Quick Links

User menu

Not signed in.

Misc Menu