[前][次][番号順一覧][スレッド一覧]

ruby-changes:44341

From: nobu <ko1@a...>
Date: Thu, 13 Oct 2016 17:06:15 +0900 (JST)
Subject: [ruby-changes:44341] nobu:r56414 (trunk): hash.c: add compact and compact! methods

nobu	2016-10-13 17:06:00 +0900 (Thu, 13 Oct 2016)

  New Revision: 56414

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56414

  Log:
    hash.c: add compact and compact! methods
    
    * hash.c (rb_hash_compact, rb_hash_compact_bang): Removes nil
      values from the original hash, to port Active Support behavior.
      [Feature #11818]

  Modified files:
    trunk/ChangeLog
    trunk/hash.c
    trunk/test/ruby/test_hash.rb
Index: test/ruby/test_hash.rb
===================================================================
--- test/ruby/test_hash.rb	(revision 56413)
+++ test/ruby/test_hash.rb	(revision 56414)
@@ -354,6 +354,14 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L354
     assert_equal({1=>2,3=>4,5=>6}, h.keep_if{true})
   end
 
+  def test_compact
+    h = @cls[a: 1, b: nil, c: false, d: true, e: nil]
+    assert_equal({a: 1, c: false, d: true}, h.compact)
+    assert_equal({a: 1, b: nil, c: false, d: true, e: nil}, h)
+    h.compact!
+    assert_equal({a: 1, c: false, d: true}, h)
+  end
+
   def test_dup
     for taint in [ false, true ]
       for frozen in [ false, true ]
Index: hash.c
===================================================================
--- hash.c	(revision 56413)
+++ hash.c	(revision 56414)
@@ -2669,6 +2669,68 @@ rb_hash_flatten(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/hash.c#L2669
     return ary;
 }
 
+static int
+delete_if_nil(VALUE key, VALUE value, VALUE hash)
+{
+    if (NIL_P(value)) {
+	return ST_DELETE;
+    }
+    return ST_CONTINUE;
+}
+
+static int
+set_if_not_nil(VALUE key, VALUE value, VALUE hash)
+{
+    if (!NIL_P(value)) {
+	rb_hash_aset(hash, key, value);
+    }
+    return ST_CONTINUE;
+}
+
+/*
+ *  call-seq:
+ *     hsh.compact -> new_hash
+ *
+ *  Returns a new hash with the nil values/key pairs removed
+ *
+ *     h = { a: 1, b: false, c: nil }
+ *     h.compact     #=> { a: 1, b: false }
+ *     h             #=> { a: 1, b: false, c: nil }
+ *
+ */
+
+static VALUE
+rb_hash_compact(VALUE hash)
+{
+    VALUE result = rb_hash_new();
+    if (!RHASH_EMPTY_P(hash)) {
+	rb_hash_foreach(hash, set_if_not_nil, result);
+    }
+    return result;
+}
+
+/*
+ *  call-seq:
+ *     hsh.compact! -> hsh
+ *
+ *  Removes all nil values from the hash.
+ *  Returns the hash.
+ *
+ *     h = { a: 1, b: false, c: nil }
+ *     h.compact!     #=> { a: 1, b: false }
+ *
+ */
+
+static VALUE
+rb_hash_compact_bang(VALUE hash)
+{
+    rb_hash_modify_check(hash);
+    if (RHASH(hash)->ntbl) {
+	rb_hash_foreach(hash, delete_if_nil, hash);
+    }
+    return hash;
+}
+
 static VALUE rb_hash_compare_by_id_p(VALUE hash);
 
 /*
@@ -4426,6 +4488,8 @@ Init_Hash(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L4488
     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
+    rb_define_method(rb_cHash,"compact", rb_hash_compact, 0);
+    rb_define_method(rb_cHash,"compact!", rb_hash_compact_bang, 0);
 
     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 56413)
+++ ChangeLog	(revision 56414)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Oct 13 17:05:57 2016  Dwain Faithfull  <dwfaithfull@g...>
+
+	* hash.c (rb_hash_compact, rb_hash_compact_bang): Removes nil
+	  values from the original hash, to port Active Support behavior.
+	  [Feature #11818]
+
 Thu Oct 13 11:35:33 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* array.c (rb_ary_sort_bang, rb_ary_sort, rb_ary_sort_by_bang):

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]