unnatural 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee0b35ed79162c58be6d1ed2af2022d18f19615d
4
- data.tar.gz: 4be5c919b28dd739b6d1cc4f9c2d8d01d49b6411
3
+ metadata.gz: e73154b350d906339b8003056791db6c5f94e098
4
+ data.tar.gz: ed95cd6dee1227b8f55cce433998685fd1b2c4bb
5
5
  SHA512:
6
- metadata.gz: 41c9475d5c6f7fb41dd962ddb1a11a2d5ac212d3186028a0d4b0c248efa91c8489a37f8973f9acbb2324e4fac62b14cdaee08990bb16b5530cf7c6e8c521cff2
7
- data.tar.gz: 5c19f5a7b5a05715d2967ea03104b3f3a7649d09bb7bac3476ea4d018707779f4f9ebd533ba8529fcb6e7ada69375a403aee9ec86017dbfdbc7c1d1eb719b1a9
6
+ metadata.gz: d0c8774280f8fdba7f71b1b39bbe63b6558a9a1b4659807b33a7c8b4acbb0c441739184e9155e0b440479fa29981403aad18bf3fc983eaca01c5d2e4fc1c5426
7
+ data.tar.gz: 96c913547575eb192399c6074237748c3defb54032fc0f5d4f3644293ba24a81c846e91589398ac09c1b6e19ad575284e2dc57c96327c1795fc02ca27e4beae8
data/README.md CHANGED
@@ -16,7 +16,7 @@ Unnatural does not (currently) provide support for:
16
16
  2. any number representation other than simple decimal integers
17
17
  3. whitespace insensitivity (i.e., one space and two spaces can be considered as different)
18
18
 
19
- Unnatural provides four algorithms, all of which use Ruby's built-in quicksort as the fundamental sort algorithm. All four modules provide module methods `.sort` for simply sorting an enumerable, and `.compare` for spaceship-operator-style comparison.
19
+ Unnatural provides four algorithms, all of which use Ruby's built-in quicksort as the fundamental sort algorithm. All four modules provide module methods `.sort` for simply sorting an enumerable, `.sort_by` for a memoized sort according to a block, and `.compare` for spaceship-operator-style comparison.
20
20
 
21
21
  ### Unnatural::Fast
22
22
 
@@ -59,6 +59,13 @@ require 'unnatural'
59
59
  sorted = Unnatural.sort(some_array_of_strings)
60
60
  ```
61
61
 
62
+ Sorting an enumerable of objects according to a block:
63
+
64
+ ```ruby
65
+ sorted = Unnatural.sort_by(some_array_of_objects) { |e| e.name }
66
+ sorted = Unnatural.sort_by(some_array_of_objects, &:name)
67
+ ```
68
+
62
69
  Defining the comparison method for a class explicitly:
63
70
 
64
71
  ```ruby
@@ -8,17 +8,28 @@ static VALUE rb_mFast;
8
8
  #define IS_LOWER(C) ('a' <= C && C <= 'z')
9
9
  #define UPCASE(C) (IS_LOWER(C) ? C - ('a' - 'A') : C)
10
10
 
11
- VALUE compare(VALUE self, VALUE a_value, VALUE b_value) {
12
- int a_length = RSTRING_LEN(a_value);
13
- int b_length = RSTRING_LEN(b_value);
14
- char* a_str = RSTRING_PTR(a_value);
15
- char* b_str = RSTRING_PTR(b_value);
16
- int a_pos = 0;
17
- int b_pos = 0;
18
- int a_number = 0;
19
- int b_number = 0;
20
- char a, b;
21
- int diff = 0;
11
+ VALUE compare(VALUE self, VALUE a_arg, VALUE b_arg) {
12
+ VALUE a_value, b_value;
13
+ int a_length, b_length, a_pos, b_pos, a_number, b_number, diff;
14
+ char *a_str, *b_str, a, b;
15
+
16
+ if (RB_TYPE_P(a_arg, T_ARRAY)) {
17
+ a_value = rb_ary_entry(a_arg, 0);
18
+ b_value = rb_ary_entry(b_arg, 0);
19
+ } else {
20
+ a_value = a_arg;
21
+ b_value = b_arg;
22
+ }
23
+
24
+ a_length = RSTRING_LEN(a_value);
25
+ b_length = RSTRING_LEN(b_value);
26
+ a_str = RSTRING_PTR(a_value);
27
+ b_str = RSTRING_PTR(b_value);
28
+ a_pos = 0;
29
+ b_pos = 0;
30
+ a_number = 0;
31
+ b_number = 0;
32
+ diff = 0;
22
33
 
23
34
  for (a_pos = 0, b_pos = 0; a_pos < a_length && b_pos < b_length; a_pos++, b_pos++) {
24
35
  a = a_str[a_pos];
@@ -6,6 +6,14 @@ unless RUBY_ENGINE == 'jruby'
6
6
  def self.sort(enumerable)
7
7
  enumerable.sort { |a, b| compare(a, b) }
8
8
  end
9
+
10
+ def self.sort_by(enumerable)
11
+ raise ArgumentError, "Block expected but none given" unless block_given?
12
+ enumerable
13
+ .map { |e| [(yield e), e] }
14
+ .sort { |a, b| compare(a, b) }
15
+ .map { |ary| ary[1] }
16
+ end
9
17
  end
10
18
  end
11
19
 
@@ -6,7 +6,20 @@ module Unnatural
6
6
  enumerable.sort { |a, b| compare(a, b) }
7
7
  end
8
8
 
9
+ def self.sort_by(enumerable)
10
+ raise ArgumentError, "Block expected but none given" unless block_given?
11
+ enumerable
12
+ .map { |e| [(yield e), e] }
13
+ .sort { |a, b| compare(a, b) }
14
+ .map { |ary| ary[1] }
15
+ end
16
+
9
17
  def self.compare(a_string, b_string)
18
+ if a_string.is_a?(Array) && b_string.is_a?(Array)
19
+ a_string = a_string.first
20
+ b_string = b_string.first
21
+ end
22
+
10
23
  a = StringScanner.new(a_string)
11
24
  b = StringScanner.new(b_string)
12
25
 
@@ -7,6 +7,11 @@ module Unnatural
7
7
  enumerable.sort_by { |s| split(s) }
8
8
  end
9
9
 
10
+ def self.sort_by(enumerable)
11
+ raise ArgumentError, "Block expected but none given" unless block_given?
12
+ enumerable.sort_by { |s| split(yield s) }
13
+ end
14
+
10
15
  def self.compare(a, b)
11
16
  split(a) <=> split(b)
12
17
  end
@@ -5,6 +5,12 @@ module Unnatural
5
5
  enumerable.sort_by { |s| substitute(s, largest) }
6
6
  end
7
7
 
8
+ def self.sort_by(enumerable)
9
+ raise ArgumentError, "Block expected but none given" unless block_given?
10
+ largest = enumerable.map { |e| yield e }.map(&:size).max
11
+ enumerable.sort_by { |s| substitute((yield s), largest) }
12
+ end
13
+
8
14
  def self.compare(a, b)
9
15
  largest = a.size < b.size ? b.size : a.size
10
16
  substitute(a, largest) <=> substitute(b, largest)
@@ -1,3 +1,3 @@
1
1
  module Unnatural
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/unnatural.rb CHANGED
@@ -19,6 +19,11 @@ module Unnatural
19
19
  @algorithm.sort(enumerable)
20
20
  end
21
21
 
22
+ def self.sort_by(enumerable)
23
+ raise ArgumentError, "Block expected but none given" unless block_given?
24
+ @algorithm.sort_by(enumerable) { |*a| yield(*a) }
25
+ end
26
+
22
27
  def self.compare(a, b)
23
28
  @algorithm.compare(a, b)
24
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unnatural
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Miller