mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
implement Array comparisons by Ruby
This commit is contained in:
@@ -95,6 +95,82 @@ class Array
|
||||
# ISO 15.2.12.5.32 (x)
|
||||
alias to_s inspect
|
||||
|
||||
##
|
||||
# Equality---Two arrays are equal if they contain the same number
|
||||
# of elements and if each element is equal to (according to
|
||||
# Object.==) the corresponding element in the other array.
|
||||
#
|
||||
# ISO 15.2.12.5.33 (x)
|
||||
def ==(other)
|
||||
other = self.__ary_eq(other)
|
||||
return false if other == false
|
||||
return true if other == true
|
||||
len = self.size
|
||||
i = 0
|
||||
while i < len
|
||||
return false if self[i] != other[i]
|
||||
i += 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
##
|
||||
# Returns <code>true</code> if +self+ and _other_ are the same object,
|
||||
# or are both arrays with the same content.
|
||||
#
|
||||
# ISO 15.2.12.5.34 (x)
|
||||
def eql?(other)
|
||||
other = self.__ary_eq(other)
|
||||
return false if other == false
|
||||
return true if other == true
|
||||
len = self.size
|
||||
i = 0
|
||||
while i < len
|
||||
return false unless self[i].eql?(other[i])
|
||||
i += 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
##
|
||||
# Comparison---Returns an integer (-1, 0, or +1)
|
||||
# if this array is less than, equal to, or greater than <i>other_ary</i>.
|
||||
# Each object in each array is compared (using <=>). If any value isn't
|
||||
# equal, then that inequality is the return value. If all the
|
||||
# values found are equal, then the return is based on a
|
||||
# comparison of the array lengths. Thus, two arrays are
|
||||
# ``equal'' according to <code>Array#<=></code> if and only if they have
|
||||
# the same length and the value of each element is equal to the
|
||||
# value of the corresponding element in the other array.
|
||||
#
|
||||
# ISO 15.2.12.5.36 (x)
|
||||
def <=>(other)
|
||||
len = self.size
|
||||
begin
|
||||
n = other.size
|
||||
rescue NoMethodError
|
||||
return nil
|
||||
end
|
||||
if len > n
|
||||
len = n
|
||||
end
|
||||
i = 0
|
||||
while i < len
|
||||
n = (self[i] <=> other[i])
|
||||
return n if n == nil
|
||||
return n if n != 0
|
||||
i += 1
|
||||
end
|
||||
len = self.size - other.size
|
||||
if len == 0
|
||||
0
|
||||
elsif len > 0
|
||||
1
|
||||
else
|
||||
-1
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Delete element with index +key+
|
||||
def delete(key, &block)
|
||||
|
||||
+5
-59
@@ -311,7 +311,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
|
||||
* [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
|
||||
*
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_value
|
||||
mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
|
||||
{
|
||||
mrb_value ary2;
|
||||
@@ -1065,72 +1065,20 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
|
||||
return mrb_ary_join(mrb, ary, sep);
|
||||
}
|
||||
|
||||
/* 15.2.12.5.33 (x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* ary == other_ary -> bool
|
||||
*
|
||||
* Equality---Two arrays are equal if they contain the same number
|
||||
* of elements and if each element is equal to (according to
|
||||
* Object.==) the corresponding element in the other array.
|
||||
*
|
||||
* [ "a", "c" ] == [ "a", "c", 7 ] #=> false
|
||||
* [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
|
||||
* [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
|
||||
mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
|
||||
{
|
||||
mrb_value ary2;
|
||||
mrb_int i;
|
||||
|
||||
mrb_get_args(mrb, "o", &ary2);
|
||||
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
|
||||
if (mrb_special_const_p(ary2)) return mrb_false_value();
|
||||
if (!mrb_array_p(ary2)) {
|
||||
if (!mrb_respond_to(mrb, ary2, mrb_intern_lit(mrb, "to_ary"))) {
|
||||
return mrb_false_value();
|
||||
}
|
||||
else {
|
||||
return mrb_bool_value(mrb_equal(mrb, ary2, ary1));
|
||||
}
|
||||
return mrb_false_value();
|
||||
}
|
||||
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
|
||||
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
||||
if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
|
||||
return mrb_false_value();
|
||||
}
|
||||
}
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.12.5.34 (x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* ary.eql?(other) -> true or false
|
||||
*
|
||||
* Returns <code>true</code> if +self+ and _other_ are the same object,
|
||||
* or are both arrays with the same content.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
|
||||
{
|
||||
mrb_value ary2;
|
||||
mrb_int i;
|
||||
|
||||
mrb_get_args(mrb, "o", &ary2);
|
||||
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
|
||||
if (!mrb_array_p(ary2)) return mrb_false_value();
|
||||
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
|
||||
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
||||
if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
|
||||
return mrb_false_value();
|
||||
}
|
||||
}
|
||||
return mrb_true_value();
|
||||
return ary2;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1169,7 +1117,5 @@ mrb_init_array(mrb_state *mrb)
|
||||
mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */
|
||||
mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */
|
||||
|
||||
mrb_define_method(mrb, a, "==", mrb_ary_equal, MRB_ARGS_REQ(1)); /* 15.2.12.5.33 (x) */
|
||||
mrb_define_method(mrb, a, "eql?", mrb_ary_eql, MRB_ARGS_REQ(1)); /* 15.2.12.5.34 (x) */
|
||||
mrb_define_method(mrb, a, "<=>", mrb_ary_cmp, MRB_ARGS_REQ(1)); /* 15.2.12.5.36 (x) */
|
||||
mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user