зеркало из https://github.com/github/ruby.git
* hash.c (rb_hash_assoc): new method.
* hash.c (rb_hash_rassoc): ditto. * hash.c (rb_hash_flatten): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12587 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
115410ecde
Коммит
fdf213b71a
|
@ -1,3 +1,11 @@
|
|||
Sat Jun 23 01:25:40 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash_assoc): new method.
|
||||
|
||||
* hash.c (rb_hash_rassoc): ditto.
|
||||
|
||||
* hash.c (rb_hash_flatten): ditto.
|
||||
|
||||
Fri Jun 22 23:55:59 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* string.c (rb_str_upto): add optional argument to specify
|
||||
|
|
4
array.c
4
array.c
|
@ -2342,10 +2342,10 @@ rb_ary_assoc(VALUE ary, VALUE key)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* array.rassoc(key) -> an_array or nil
|
||||
* array.rassoc(obj) -> an_array or nil
|
||||
*
|
||||
* Searches through the array whose elements are also arrays. Compares
|
||||
* <em>key</em> with the second element of each contained array using
|
||||
* _obj_ with the second element of each contained array using
|
||||
* <code>==</code>. Returns the first contained array that matches. See
|
||||
* also <code>Array#assoc</code>.
|
||||
*
|
||||
|
|
147
hash.c
147
hash.c
|
@ -1517,6 +1517,103 @@ rb_hash_merge(VALUE hash1, VALUE hash2)
|
|||
return rb_hash_update(rb_obj_dup(hash1), hash2);
|
||||
}
|
||||
|
||||
static int
|
||||
assoc_i(VALUE key, VALUE val, VALUE *args)
|
||||
{
|
||||
if (key == Qundef) return ST_CONTINUE;
|
||||
if (RTEST(rb_equal(args[0], key))) {
|
||||
args[1] = rb_assoc_new(key, val);
|
||||
return ST_STOP;
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* hash.assoc(obj) -> an_array or nil
|
||||
*
|
||||
* Searches through the hash comparing _obj_ with the key using <code>==</code>.
|
||||
* Returns the key-value pair (two elements array) or +nil+
|
||||
* if no match is found. See <code>Array#assoc</code>.
|
||||
*
|
||||
* h = {"colors" => ["red", "blue", "green"],
|
||||
* "letters" => ["a", "b", "c" ]}
|
||||
* h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
|
||||
* h.assoc("foo") #=> nil
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_hash_assoc(VALUE hash, VALUE obj)
|
||||
{
|
||||
VALUE args[2];
|
||||
|
||||
args[0] = obj;
|
||||
args[1] = Qnil;
|
||||
rb_hash_foreach(hash, assoc_i, (st_data_t)args);
|
||||
return args[1];
|
||||
}
|
||||
|
||||
static int
|
||||
rassoc_i(VALUE key, VALUE val, VALUE *args)
|
||||
{
|
||||
if (key == Qundef) return ST_CONTINUE;
|
||||
if (RTEST(rb_equal(args[0], val))) {
|
||||
args[1] = rb_assoc_new(key, val);
|
||||
return ST_STOP;
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* hash.rassoc(key) -> an_array or nil
|
||||
*
|
||||
* Searches through the hash comparing _obj_ with the value using <code>==</code>.
|
||||
* Returns the first key-value pair (two elements array) that matches. See
|
||||
* also <code>Array#rassoc</code>.
|
||||
*
|
||||
* a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
|
||||
* a.rassoc("two") #=> [2, "two"]
|
||||
* a.rassoc("four") #=> nil
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_hash_rassoc(VALUE hash, VALUE obj)
|
||||
{
|
||||
VALUE args[2];
|
||||
|
||||
args[0] = obj;
|
||||
args[1] = Qnil;
|
||||
rb_hash_foreach(hash, rassoc_i, (st_data_t)args);
|
||||
return args[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* hash.flatten -> an_array
|
||||
* hash.flatten(level) -> an_array
|
||||
*
|
||||
* Returns a new array that is a one-dimensional flattening of this
|
||||
* hash. That is, for every key or value that is an array, extract
|
||||
* its elements into the new array. Unlike Array#flatten, this
|
||||
* method does not flatten recursively by default. If the optional
|
||||
* <i>level</i> argument determins the level of recursion to flatten.
|
||||
*
|
||||
* a = {1=> "one", 2 => [2,"two"], 3 => "three"}
|
||||
* a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
|
||||
* a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
|
||||
{
|
||||
VALUE ary, lv;
|
||||
|
||||
ary = rb_hash_to_a(hash);
|
||||
rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static struct st_hash_type identhash = {
|
||||
st_numcmp,
|
||||
st_numhash,
|
||||
|
@ -2176,18 +2273,33 @@ env_has_key(VALUE env, VALUE key)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
env_has_value(VALUE dmy, VALUE value)
|
||||
env_assoc(VALUE env, VALUE key)
|
||||
{
|
||||
char *s, *e;
|
||||
|
||||
rb_secure(4);
|
||||
s = StringValuePtr(key);
|
||||
if (strlen(s) != RSTRING_LEN(key))
|
||||
rb_raise(rb_eArgError, "bad environment variable name");
|
||||
e = getenv(s);
|
||||
if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
env_has_value(VALUE dmy, VALUE obj)
|
||||
{
|
||||
char **env;
|
||||
|
||||
rb_secure(4);
|
||||
if (TYPE(value) != T_STRING) return Qfalse;
|
||||
obj = rb_check_string_type(obj);
|
||||
if (NIL_P(obj)) return Qnil;
|
||||
env = GET_ENVIRON(environ);
|
||||
while (*env) {
|
||||
char *s = strchr(*env, '=');
|
||||
if (s++) {
|
||||
long len = strlen(s);
|
||||
if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
|
||||
if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
|
||||
FREE_ENVIRON(environ);
|
||||
return Qtrue;
|
||||
}
|
||||
|
@ -2198,6 +2310,30 @@ env_has_value(VALUE dmy, VALUE value)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
env_rassoc(VALUE dmy, VALUE obj)
|
||||
{
|
||||
char **env;
|
||||
|
||||
rb_secure(4);
|
||||
obj = rb_check_string_type(obj);
|
||||
if (NIL_P(obj)) return Qnil;
|
||||
env = GET_ENVIRON(environ);
|
||||
while (*env) {
|
||||
char *s = strchr(*env, '=');
|
||||
if (s++) {
|
||||
long len = strlen(s);
|
||||
if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
|
||||
FREE_ENVIRON(environ);
|
||||
return rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
|
||||
}
|
||||
}
|
||||
env++;
|
||||
}
|
||||
FREE_ENVIRON(environ);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
env_key(VALUE dmy, VALUE value)
|
||||
{
|
||||
|
@ -2407,6 +2543,9 @@ Init_Hash(void)
|
|||
rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
|
||||
rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
|
||||
rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
|
||||
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,"include?", rb_hash_has_key, 1);
|
||||
rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
|
||||
|
@ -2460,6 +2599,8 @@ Init_Hash(void)
|
|||
rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
|
||||
rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
|
||||
rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
|
||||
rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
|
||||
rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
|
||||
|
||||
rb_define_global_const("ENV", envtbl);
|
||||
#else /* __MACOS__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче