Skip to content

Commit

Permalink
Merge pull request #10 from eReGeBe/master
Browse files Browse the repository at this point in the history
Add optional block to allow sorting of arrays of arbitrary objects
  • Loading branch information
mislav committed Aug 7, 2016
2 parents e1b7752 + 9e6f6da commit 9853b73
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -15,6 +15,12 @@ VersionSorter.sort(versions)
#=> 2.0
```

You can also sort arrays of arbitrary objects by providing a block.

```rb
VersionSorter.sort(tags) { |tag| tag.name }
```

Library API:

```rb
Expand Down
11 changes: 9 additions & 2 deletions ext/version_sorter/version_sorter.c
Expand Up @@ -185,8 +185,15 @@ rb_version_sort_1(VALUE rb_self, VALUE rb_version_array, compare_callback_t cmp)
versions = xcalloc(length, sizeof(struct version_number *));

for (i = 0; i < length; ++i) {
VALUE rb_version = rb_ary_entry(rb_version_array, i);
versions[i] = parse_version_number(StringValuePtr(rb_version));
VALUE rb_version, rb_version_string;

rb_version = rb_ary_entry(rb_version_array, i);
if (rb_block_given_p())
rb_version_string = rb_yield(rb_version);
else
rb_version_string = rb_version;

versions[i] = parse_version_number(StringValuePtr(rb_version_string));
versions[i]->rb_version = rb_version;
}

Expand Down
20 changes: 20 additions & 0 deletions test/version_sorter_test.rb
Expand Up @@ -4,6 +4,14 @@
require 'rubygems/version'

class VersionSorterTest < Test::Unit::TestCase
def setup
version_struct = Struct.new(:name)

@version1 = version_struct.new("1.0")
@version2 = version_struct.new("2.0")
@version10 = version_struct.new("10.0")
end

def test_sorts_versions_correctly
versions = %w(1.0.9 1.0.10 2.0 3.1.4.2 1.0.9a)
sorted_versions = %w( 1.0.9a 1.0.9 1.0.10 2.0 3.1.4.2 )
Expand Down Expand Up @@ -71,6 +79,18 @@ def test_rsort_bang
assert_equal ["10.0", "2.0", "1.0"], versions
end

def test_sort_block
versions = [@version10, @version1, @version2]
sorted = VersionSorter.sort(versions) { |version| version.name }
assert_equal [@version1, @version2, @version10], sorted
end

def test_rsort_block
versions = [@version10, @version1, @version2]
sorted = VersionSorter.rsort(versions) { |version| version.name }
assert_equal [@version10, @version2, @version1], sorted
end

def shuffle(array)
array, result = array.dup, []
result << array.delete_at(rand(array.size)) until array.size.zero?
Expand Down

0 comments on commit 9853b73

Please sign in to comment.