On 20 Mar 2010, at 20:17, Brian S wrote: > Overview: > > Current code uses an FB dynamic array of records. My goal is to incrementally change the code to CF so the code that accesses the record fields does not have to be changed. Array sorting and searching are required. Creating a mutable CFArray of CFMutableDictionaryRefs ( see: SortDescriptor example ) is a good technical solution but would require a switch away from FB records. > > Detail, Discussion/Questions: > > CFArraySortValues() and CFArrayBSearchValues() appear ideal but their operation is not clear to me given the use of an array of FB records ( really CFDataRefs loaded into a CFArray ). Both calls use a CFComparatorFunction ( and this type is used to cast the comparator function in C code ---i.e. (CFComparatorFunction)CFStringCompare ) which appears to be a direct call to a standard CF call ( such as CFStringCompare() or others ). Since my code uses records, I need a user callback function ( which I believe the comparator can be ) to compare on specific record fields. The mechanics used for the comparator function with CFArraySortValues() should be the same for CFArrayBSearchValues(). I'm hoping someone has a working example of using at least CFArraySortValues(). I wonder if something like this will do what you want? Knocked together very quickly so I may have missed something. '--------------- include "ConsoleWindow" begin record MyInfo dim as Str255 name dim as long age end record begin enum _kNameField _kAgeField end enum local fn MySorter( val1 as CFDataRef, val2 as CFDataRef, context as pointer) as CFComparisonResult '~'1 dim as MyInfo info1, info2 dim as CFComparisonResult result : result = _kCFCompareEqualTo dim as long sortField : sortField = context CFDataGetBytes( val1, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info1 ) CFDataGetBytes( val2, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info2 ) select ( sortField ) case _kNameField// name if ( info1.name > info2.name ) then result = _kCFCompareGreaterThan case _kAgeField// age if ( info1.age > info2.age ) then result = _kCFCompareGreaterThan end select end fn = result local fn PrintArray( array as CFMutableArrayRef ) '~'1 dim as CFDataRef dataRef dim as MyInfo info dim as CFIndex count, index count = fn CFArrayGetCount( array ) long if ( count ) for index = 0 to count - 1 dataRef = fn CFArrayGetValueAtIndex( array, index ) long if ( dataRef ) CFDataGetBytes( dataRef, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info ) print info.name,info.age end if next index end if end fn dim as CFMutableArrayRef array dim as CFDataRef dataRef dim as MyInfo info array = fn CFArrayCreateMutable( _kCFAllocatorDefault, 0, @kCFTypeArrayCallBacks ) info.name = "Robert" info.age = 38 dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) ) CFArrayAppendValue( array, dataRef ) CFRelease( dataRef ) info.name = "Brian" info.age = 43 dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) ) CFArrayAppendValue( array, dataRef ) CFRelease( dataRef ) info.name = "Michele" info.age = 27 dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) ) CFArrayAppendValue( array, dataRef ) CFRelease( dataRef ) print "- unsorted -" fn PrintArray( array ) print : print "- sort by name -" CFArraySortValues( array, fn CFRangeMake( 0, fn CFArrayGetCount( array ) ), @fn MySorter, _kNameField ) fn PrintArray( array ) print : print "- sort by age -" CFArraySortValues( array, fn CFRangeMake( 0, fn CFArrayGetCount( array ) ), @fn MySorter, _kAgeField ) fn PrintArray( array ) CFRelease( array ) '--------------- Bernie