Re: A custom way to sort EOs by key ?
Re: A custom way to sort EOs by key ?
- Subject: Re: A custom way to sort EOs by key ?
- From: "Matthew W. Taylor" <email@hidden>
- Date: Thu, 10 May 2007 16:19:48 -0500
- Organization: MMLC, Northwestern University
It sounds like what you want to do is perform "Natural" sort ordering to the results. This kind of ordering is a little more modern in the sense that it's new to the Finder in Mac OS X, and well, to my knowledge Windows Explorer still doesn't organize file lists in this way.
Either way, you can do something like this to sort your lists of EO's once fetched:
try {
sortedArray = unsortedArray.sortedArrayUsingComparator(new EOCustomObjectNaturalOrderComparator("nameOfKeyToSortBy"));
}
catch (Exception e) {
NSLog.out.appendln("sorting problem: " + e.getMessage());
sortedArray = unsortedArray;
}
And, here is how I have implemented an NSComparator from the code originally written by Martin Pool in C, with an initial Java translation by Pierre-Luc Paour:
-=- BEGIN Java file -=-
/*
// EOCustomObjectNaturalOrderComparator.java
// DiLL
//
// Created by Matthew Taylor on 7/28/05.
// Northwestern University.
*/
/*
Based entirely on:
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <email@hidden>
Based on the C version by Martin Pool, of which this is more or less a straight conversion.
Copyright (C) 2000 by Martin Pool <email@hidden>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
import java.util.*;
import com.webobjects.eocontrol.EOCustomObject;
import com.webobjects.foundation.NSComparator;
public class EOCustomObjectNaturalOrderComparator extends NSComparator {
String nameOfObjectKeyToSortBy;
public EOCustomObjectNaturalOrderComparator(String newNameOfObjectKeyToSortBy) {
nameOfObjectKeyToSortBy = newNameOfObjectKeyToSortBy;
}
int compareRight(String a, String b) {
int bias = 0;
int ia = 0;
int ib = 0;
// The longest run of digits wins. That aside, the greatest
// value wins, but we can't know that it will until we've scanned
// both numbers to know that they have the same magnitude, so we
// remember it in BIAS.
for (;; ia++, ib++) {
char ca = charAt(a, ia);
char cb = charAt(b, ib);
if (!Character.isDigit(ca)
&& !Character.isDigit(cb)) {
return bias;
} else if (!Character.isDigit(ca)) {
return NSComparator.OrderedAscending;
} else if (!Character.isDigit(cb)) {
return NSComparator.OrderedDescending;
} else if (ca < cb) {
if (bias == 0) {
bias = -1;
}
} else if (ca > cb) {
if (bias == 0)
bias = +1;
} else if (ca == 0 && cb == 0) {
return bias;
}
}
}
public int compare(Object o1, Object o2) {
String a = (String)(((EOCustomObject)o1).storedValueForKey(nameOfObjectKeyToSortBy));
String b = (String)(((EOCustomObject)o2).storedValueForKey(nameOfObjectKeyToSortBy));
int ia = 0, ib = 0;
int nza = 0, nzb = 0;
char ca, cb;
int result;
while (true) {
// only count the number of zeroes leading the last number compared
nza = nzb = 0;
ca = charAt(a, ia); cb = charAt(b, ib);
// skip over leading spaces or zeros
while (Character.isSpaceChar(ca) || ca == '0') {
if (ca == '0') {
nza++;
} else {
// only count consecutive zeroes
nza = 0;
}
ca = charAt(a, ++ia);
}
while (Character.isSpaceChar(cb) || cb == '0') {
if (cb == '0') {
nzb++;
} else {
// only count consecutive zeroes
nzb = 0;
}
cb = charAt(b, ++ib);
}
// process run of digits
if (Character.isDigit(ca) && Character.isDigit(cb)) {
if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) {
return result;
}
}
if (ca == 0 && cb == 0) {
// The strings compare the same. Perhaps the caller
// will want to call strcmp to break the tie.
// return nza - nzb;
return NSComparator.OrderedSame;
}
if (ca < cb) {
return NSComparator.OrderedAscending;
} else if (ca > cb) {
return NSComparator.OrderedDescending;
}
++ia; ++ib;
}
}
static char charAt(String s, int i) {
if (i >= s.length()) {
return 0;
} else {
return s.charAt(i);
}
}
}
-=- END Java file -=-
On Thu, 10 May 2007 17:00:26 -0400, Robert Walker <email@hidden> wrote:
>> You could also add an "ordering" column to the EO. Then you sort on
>> the "ordering" column.
>
> Does anyone know if WO or WOnder has build-in support for this. If
> so that would be nice to have available included.
>
> Ruby on Rails does have this feature built-in. It's called
> "acts_as_list" and the Rails framework completely automates this
> feature, with a very simple setup on the developer's end.
>
> On May 10, 2007, at 1:06 PM, David Holt wrote:
>
>> You could also add an "ordering" column to the EO. Then you sort on
>> the "ordering" column.
>>
>> David
>>
>> On 10 May 2007, at 8:27 AM, Ken Anderson wrote:
>>
>>> Fabrice,
>>>
>>> I would suggest, if possible, to separate the number from the name
>>> in the EO. That way, you could just sort on the number, or a
>>> combination of name and number.
>>>
>>> Even with your own sorting, you're going to have to pull the
>>> number off the end of the string to sort it properly.
>>>
>>> Do you want to do this with a database query, or in memory? If in
>>> memory, you could create a method that pulls the number off and
>>> returns that number, then use that method as the key for sorting
>>> in memory.
>>>
>>> Ken
>>>
>>> On May 10, 2007, at 11:21 AM, Fabrice Pipart wrote:
>>>
>>>> Hi Dear List !
>>>>
>>>> I have been looking for way to sort my EOs in a custom way for
>>>> hours and did not find any solution.
>>>> I wondered if someone had a solution for this.
>>>> I only want to do that sorting in memory with
>>>> EOSortOrdering .sortOrderingWithKey(String key, NSSelector selector)
>>>>
>>>> Let's say I have a Screen EO
>>>> Screen has a name
>>>> Let's say I have EOs with names "Screen1", "Screen2", "Screen11",
>>>> "Screen22", "Screen3"
>>>> WebObjects using EOSortOrdering.CompareAscending allows me to an
>>>> array of those EOs sorted like this :
>>>> Screen1
>>>> Screen11
>>>> Screen2
>>>> Screen22
>>>> Screen3
>>>>
>>>> Wouldn't it be great to be able to sort them like this?
>>>> Screen1
>>>> Screen2
>>>> Screen3
>>>> Screen11
>>>> Screen22
>>>>
>>>> So I tried to understand how to subclass something, create a
>>>> corresponding NSSelector like are EOSortOrdering.CompareAscending
>>>> and such... no luck :-(
>>>>
>>>> Does anyone have an idea of how this could be done???
>>>>
>>>>
>>>> Regards
>>>>
>>>>
>>>> www.easyshadow.com
>>>>
>>>> International Corporate Consulting
>>>> Palais de la Scala
>>>> 1 avenue Henri Dunant
>>>> Suite 1155
>>>> MC - 98000 Monaco
>>>>
>>>> Skype: fabrice.pipart
>>>> Tel. +377 97 98 21 04 (direct)
>>>> Fax. +377 97 70 88 07
>>>>
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list (email@hidden)
>>>> Help/Unsubscribe/Update your Subscription:
>>>> 40anderhome.com
>>>>
>>>> This email sent to email@hidden
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list (email@hidden)
>>> Help/Unsubscribe/Update your Subscription:
>>> email@hidden
>>>
>>> This email sent to email@hidden
>>
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>> 40mac.com
>>
>> This email sent to email@hidden
>
> --
> Robert Walker
> email@hidden
>
>
>
>
>
>
>
_______________________________________________
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