aboutsummaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-13 08:06:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-10-13 08:06:00 +0000
commitc4427fc7fe081c7dc88207e469100d835d170c37 (patch)
tree6465e05d16a1f6deb7ff51230227e4b75d99d4d4 /hash.c
parentfb5a255755b44d80f181b58cfea1647d0d64148a (diff)
downloadruby-c4427fc7fe081c7dc88207e469100d835d170c37.tar.gz
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56414 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/hash.c b/hash.c
index 2f2b1f169e..630269d125 100644
--- a/hash.c
+++ b/hash.c
@@ -2669,6 +2669,68 @@ rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
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)
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);