Commit 24c345fe authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge branch 'vvakame-add-hash-compact'

parents f9c3ebd2 6c61a606
...@@ -114,6 +114,22 @@ class Hash ...@@ -114,6 +114,22 @@ class Hash
alias update merge! alias update merge!
##
# call-seq:
# hsh.compact -> new_hsh
#
# 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 }
#
def compact
result = self.dup
result.compact!
result
end
## ##
# call-seq: # call-seq:
# hsh.fetch(key [, default] ) -> obj # hsh.fetch(key [, default] ) -> obj
......
...@@ -36,6 +36,41 @@ hash_values_at(mrb_state *mrb, mrb_value hash) ...@@ -36,6 +36,41 @@ hash_values_at(mrb_state *mrb, mrb_value hash)
return 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 mrb_value
hash_compact_bang(mrb_state *mrb, mrb_value hash)
{
khiter_t k;
khash_t(ht) *h = RHASH_TBL(hash);
mrb_int n = -1;
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h, k)) {
mrb_value val = kh_value(h, k).v;
khiter_t k2;
if (mrb_nil_p(val)) {
kh_del(ht, mrb, h, k);
n = kh_value(h, k).n;
for (k2 = kh_begin(h); k2 != kh_end(h); k2++) {
if (!kh_exist(h, k2)) continue;
if (kh_value(h, k2).n > n) kh_value(h, k2).n--;
}
}
}
}
if (n < 0) return mrb_nil_value();
return hash;
}
void void
mrb_mruby_hash_ext_gem_init(mrb_state *mrb) mrb_mruby_hash_ext_gem_init(mrb_state *mrb)
{ {
...@@ -43,6 +78,7 @@ mrb_mruby_hash_ext_gem_init(mrb_state *mrb) ...@@ -43,6 +78,7 @@ mrb_mruby_hash_ext_gem_init(mrb_state *mrb)
h = mrb->hash_class; h = mrb->hash_class;
mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY()); mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY());
mrb_define_method(mrb, h, "compact!", hash_compact_bang, MRB_ARGS_NONE());
} }
void void
......
...@@ -82,6 +82,20 @@ assert('Hash#values_at') do ...@@ -82,6 +82,20 @@ assert('Hash#values_at') do
assert_equal keys, h.values_at(*keys) assert_equal keys, h.values_at(*keys)
end end
assert('Hash#compact') do
h = { "cat" => "feline", "dog" => nil, "cow" => false }
assert_equal({ "cat" => "feline", "cow" => false }, h.compact)
assert_equal({ "cat" => "feline", "dog" => nil, "cow" => false }, h)
end
assert('Hash#compact!') do
h = { "cat" => "feline", "dog" => nil, "cow" => false }
h.compact!
assert_equal({ "cat" => "feline", "cow" => false }, h)
end
assert('Hash#fetch') do assert('Hash#fetch') do
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
assert_equal "feline", h.fetch("cat") assert_equal "feline", h.fetch("cat")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment