avm2: Implement `Array.sortOn`
This commit is contained in:
parent
0aa2c50118
commit
3b7922d222
|
@ -797,9 +797,9 @@ where
|
||||||
|
|
||||||
/// Sort array storage.
|
/// Sort array storage.
|
||||||
///
|
///
|
||||||
/// This function expects it's values to have been pre-enumerated. They will be
|
/// This function expects it's values to have been pre-enumerated and
|
||||||
/// sorted in-place. It is the caller's responsibility to place the resulting
|
/// pre-resolved. They will be sorted in-place. It is the caller's
|
||||||
/// half of the sorted array wherever.
|
/// responsibility to place the resulting half of the sorted array wherever.
|
||||||
///
|
///
|
||||||
/// This function will reverse the sort order if `Descending` sort is requested.
|
/// This function will reverse the sort order if `Descending` sort is requested.
|
||||||
///
|
///
|
||||||
|
@ -810,7 +810,7 @@ where
|
||||||
/// contents of the `values` array will be sorted in a random order.
|
/// contents of the `values` array will be sorted in a random order.
|
||||||
fn sort_inner<'a, 'gc, 'ctxt, C>(
|
fn sort_inner<'a, 'gc, 'ctxt, C>(
|
||||||
activation: &mut Activation<'a, 'gc, 'ctxt>,
|
activation: &mut Activation<'a, 'gc, 'ctxt>,
|
||||||
values: &mut [(usize, Option<Value<'gc>>)],
|
values: &mut [(usize, Value<'gc>)],
|
||||||
options: EnumSet<SortOptions>,
|
options: EnumSet<SortOptions>,
|
||||||
mut sort_func: C,
|
mut sort_func: C,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
|
@ -821,8 +821,8 @@ where
|
||||||
let mut error_signal = Ok(());
|
let mut error_signal = Ok(());
|
||||||
|
|
||||||
values.sort_unstable_by(|(_a_index, a), (_b_index, b)| {
|
values.sort_unstable_by(|(_a_index, a), (_b_index, b)| {
|
||||||
let unresolved_a = a.clone().unwrap_or(Value::Undefined);
|
let unresolved_a = a.clone();
|
||||||
let unresolved_b = b.clone().unwrap_or(Value::Undefined);
|
let unresolved_b = b.clone();
|
||||||
|
|
||||||
if matches!(unresolved_a, Value::Undefined) && matches!(unresolved_b, Value::Undefined) {
|
if matches!(unresolved_a, Value::Undefined) && matches!(unresolved_b, Value::Undefined) {
|
||||||
unique_sort_satisfied = false;
|
unique_sort_satisfied = false;
|
||||||
|
@ -833,11 +833,7 @@ where
|
||||||
return Ordering::Less;
|
return Ordering::Less;
|
||||||
}
|
}
|
||||||
|
|
||||||
match sort_func(
|
match sort_func(activation, a.clone(), b.clone()) {
|
||||||
activation,
|
|
||||||
a.clone().unwrap_or(Value::Undefined),
|
|
||||||
b.clone().unwrap_or(Value::Undefined),
|
|
||||||
) {
|
|
||||||
Ok(Ordering::Equal) => {
|
Ok(Ordering::Equal) => {
|
||||||
unique_sort_satisfied = false;
|
unique_sort_satisfied = false;
|
||||||
Ordering::Equal
|
Ordering::Equal
|
||||||
|
@ -897,6 +893,86 @@ fn compare_numeric<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Take a sorted set of values and produce the result requested by the caller.
|
||||||
|
fn sort_postprocess<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
options: EnumSet<SortOptions>,
|
||||||
|
unique_satisfied: bool,
|
||||||
|
values: Vec<(usize, Value<'gc>)>,
|
||||||
|
) -> Result<Value<'gc>, Error> {
|
||||||
|
if unique_satisfied {
|
||||||
|
if options.contains(SortOptions::ReturnIndexedArray) {
|
||||||
|
return build_array(
|
||||||
|
activation,
|
||||||
|
ArrayStorage::from_storage(
|
||||||
|
values
|
||||||
|
.iter()
|
||||||
|
.map(|(i, _v)| Some(i.clone().into()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if let Some(mut old_array) = this.as_array_storage_mut(activation.context.gc_context) {
|
||||||
|
let mut new_vec = Vec::new();
|
||||||
|
|
||||||
|
for (src, v) in values.iter() {
|
||||||
|
if old_array.get(*src).is_none() && !matches!(v, Value::Undefined) {
|
||||||
|
new_vec.push(Some(v.clone()));
|
||||||
|
} else {
|
||||||
|
new_vec.push(old_array.get(*src).clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_array = ArrayStorage::from_storage(new_vec);
|
||||||
|
|
||||||
|
swap(&mut *old_array, &mut new_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(this.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a value, extract it's array values.
|
||||||
|
///
|
||||||
|
/// If the value is not an array, this function yields `None`.
|
||||||
|
fn extract_array_values<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
value: Value<'gc>,
|
||||||
|
) -> Result<Option<Vec<Value<'gc>>>, Error> {
|
||||||
|
let object = value.coerce_to_object(activation).ok();
|
||||||
|
let holey_vec = if let Some(object) = object {
|
||||||
|
if let Some(field_array) = object.as_array_storage() {
|
||||||
|
let mut array = Vec::new();
|
||||||
|
|
||||||
|
for v in field_array.iter() {
|
||||||
|
array.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
array
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut unholey_vec = Vec::new();
|
||||||
|
for (i, v) in holey_vec.iter().enumerate() {
|
||||||
|
unholey_vec.push(resolve_array_hole(
|
||||||
|
activation,
|
||||||
|
object.unwrap(),
|
||||||
|
i,
|
||||||
|
v.clone(),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(unholey_vec))
|
||||||
|
}
|
||||||
|
|
||||||
/// Impl `Array.sort`
|
/// Impl `Array.sort`
|
||||||
pub fn sort<'gc>(
|
pub fn sort<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
@ -927,16 +1003,17 @@ pub fn sort<'gc>(
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut values = if let Some(array) = this.as_array_storage() {
|
let mut values = if let Some(values) = extract_array_values(activation, this.into())? {
|
||||||
array
|
values
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.collect::<Vec<(usize, Option<Value<'gc>>)>>()
|
.map(|(i, v)| (i, v.clone()))
|
||||||
|
.collect::<Vec<(usize, Value<'gc>)>>()
|
||||||
} else {
|
} else {
|
||||||
return Ok(0.into());
|
return Ok(0.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let unique_satisified = if let Some(v) = compare_fnc {
|
let unique_satisfied = if let Some(v) = compare_fnc {
|
||||||
sort_inner(
|
sort_inner(
|
||||||
activation,
|
activation,
|
||||||
&mut values,
|
&mut values,
|
||||||
|
@ -973,29 +1050,145 @@ pub fn sort<'gc>(
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
if unique_satisified {
|
return sort_postprocess(activation, this, options, unique_satisfied, values);
|
||||||
if options.contains(SortOptions::ReturnIndexedArray) {
|
}
|
||||||
return build_array(
|
|
||||||
|
Ok(0.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a value, extract it's array values.
|
||||||
|
///
|
||||||
|
/// If the value is not an array, it will be returned as if it was present in a
|
||||||
|
/// one-element array containing itself. This is intended for use with parsing
|
||||||
|
/// parameters which are optionally arrays.
|
||||||
|
fn extract_maybe_array_values<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
value: Value<'gc>,
|
||||||
|
) -> Result<Vec<Value<'gc>>, Error> {
|
||||||
|
Ok(extract_array_values(activation, value.clone())?.unwrap_or_else(|| vec![value]))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a value, extract it's array values and coerce them to strings.
|
||||||
|
///
|
||||||
|
/// If the value is not an array, it will be returned as if it was present in a
|
||||||
|
/// one-element array containing itself. This is intended for use with parsing
|
||||||
|
/// parameters which are optionally arrays. The returned value will still be
|
||||||
|
/// coerced into a string in this case.
|
||||||
|
fn extract_maybe_array_strings<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
value: Value<'gc>,
|
||||||
|
) -> Result<Vec<AvmString<'gc>>, Error> {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
|
for value in extract_maybe_array_values(activation, value)? {
|
||||||
|
out.push(value.coerce_to_string(activation)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a value, extract it's array values and coerce them to enumsets.
|
||||||
|
///
|
||||||
|
/// If the value is not an array, it will be returned as if it was present in a
|
||||||
|
/// one-element array containing itself. This is intended for use with parsing
|
||||||
|
/// parameters which are optionally arrays. The returned value will still be
|
||||||
|
/// coerced into a string in this case.
|
||||||
|
fn extract_maybe_array_enumsets<'gc, E>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
value: Value<'gc>,
|
||||||
|
) -> Result<Vec<EnumSet<E>>, Error>
|
||||||
|
where
|
||||||
|
E: EnumSetType,
|
||||||
|
{
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
|
for value in extract_maybe_array_values(activation, value)? {
|
||||||
|
out.push(value.coerce_to_enumset(activation)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Impl `Array.sortOn`
|
||||||
|
pub fn sort_on<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error> {
|
||||||
|
if let Some(this) = this {
|
||||||
|
if let Some(field_names_value) = args.get(0).cloned() {
|
||||||
|
let field_names = extract_maybe_array_strings(activation, field_names_value)?;
|
||||||
|
let mut options = extract_maybe_array_enumsets(
|
||||||
activation,
|
activation,
|
||||||
ArrayStorage::from_storage(
|
args.get(1).cloned().unwrap_or_else(|| 0.into()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let first_option = options
|
||||||
|
.get(0)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(EnumSet::empty)
|
||||||
|
.intersection(SortOptions::UniqueSort | SortOptions::ReturnIndexedArray);
|
||||||
|
let mut values = if let Some(values) = extract_array_values(activation, this.into())? {
|
||||||
values
|
values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(i, _v)| Some(i.clone().into()))
|
.enumerate()
|
||||||
.collect(),
|
.map(|(i, v)| (i, v.clone()))
|
||||||
),
|
.collect::<Vec<(usize, Value<'gc>)>>()
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
let mut new_array =
|
return Ok(0.into());
|
||||||
ArrayStorage::from_storage(values.iter().map(|(_i, v)| v.clone()).collect());
|
};
|
||||||
|
|
||||||
if let Some(mut old_array) =
|
if options.len() < field_names.len() {
|
||||||
this.as_array_storage_mut(activation.context.gc_context)
|
options.resize(
|
||||||
{
|
field_names.len(),
|
||||||
swap(&mut *old_array, &mut new_array);
|
options.last().cloned().unwrap_or_else(EnumSet::empty),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(this.into());
|
let unique_satisfied = sort_inner(
|
||||||
|
activation,
|
||||||
|
&mut values,
|
||||||
|
first_option,
|
||||||
|
constrain(|activation, a, b| {
|
||||||
|
for (field_name, options) in field_names.iter().zip(options.iter()) {
|
||||||
|
let mut a_object = a.coerce_to_object(activation)?;
|
||||||
|
let a_field = a_object.get_property(
|
||||||
|
a_object,
|
||||||
|
&QName::new(Namespace::public_namespace(), *field_name),
|
||||||
|
activation,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut b_object = b.coerce_to_object(activation)?;
|
||||||
|
let b_field = b_object.get_property(
|
||||||
|
b_object,
|
||||||
|
&QName::new(Namespace::public_namespace(), *field_name),
|
||||||
|
activation,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let ord = if options.contains(SortOptions::Numeric) {
|
||||||
|
compare_numeric(activation, a_field, b_field)?
|
||||||
|
} else if options.contains(SortOptions::CaseInsensitive) {
|
||||||
|
compare_string_case_insensitive(activation, a_field, b_field)?
|
||||||
|
} else {
|
||||||
|
compare_string_case_sensitive(activation, a_field, b_field)?
|
||||||
|
};
|
||||||
|
|
||||||
|
if matches!(ord, Ordering::Equal) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.contains(SortOptions::Descending) {
|
||||||
|
return Ok(ord.reverse());
|
||||||
|
} else {
|
||||||
|
return Ok(ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Ordering::Equal)
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return sort_postprocess(activation, this, first_option, unique_satisfied, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,6 +1310,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
|
||||||
Method::from_builtin(sort),
|
Method::from_builtin(sort),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
class.write(mc).define_instance_trait(Trait::from_method(
|
||||||
|
QName::new(Namespace::public_namespace(), "sortOn"),
|
||||||
|
Method::from_builtin(sort_on),
|
||||||
|
));
|
||||||
|
|
||||||
class.write(mc).define_class_trait(Trait::from_const(
|
class.write(mc).define_class_trait(Trait::from_const(
|
||||||
QName::new(Namespace::public_namespace(), "CASEINSENSITIVE"),
|
QName::new(Namespace::public_namespace(), "CASEINSENSITIVE"),
|
||||||
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
|
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
|
||||||
|
|
|
@ -380,6 +380,7 @@ swf_tests! {
|
||||||
(as3_array_slice, "avm2/array_slice", 1),
|
(as3_array_slice, "avm2/array_slice", 1),
|
||||||
(as3_array_splice, "avm2/array_splice", 1),
|
(as3_array_splice, "avm2/array_splice", 1),
|
||||||
(as3_array_sort, "avm2/array_sort", 1),
|
(as3_array_sort, "avm2/array_sort", 1),
|
||||||
|
(as3_array_sorton, "avm2/array_sorton", 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.
|
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
package {
|
||||||
|
public class Test {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_array(a) {
|
||||||
|
for (var i = 0; i < a.length; i += 1) {
|
||||||
|
trace(a[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_array_props(a) {
|
||||||
|
for (var i = 0; i < a.length; i += 1) {
|
||||||
|
if (a[i] !== undefined && a[i] !== null) {
|
||||||
|
trace(a[i].numprop);
|
||||||
|
trace(a[i].strprop);
|
||||||
|
} else {
|
||||||
|
trace("//(undefined value omitted)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fresh_array_a() {
|
||||||
|
trace("//var a = new Array(item1, item2, item3)");
|
||||||
|
var a = new Array(item1, item2, item3);
|
||||||
|
|
||||||
|
trace("//a[4] = item5;");
|
||||||
|
a[4] = item5;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_holes(a) {
|
||||||
|
var item4 = {"numprop": 9, "strprop": "boo", "numprop2": 4};
|
||||||
|
|
||||||
|
trace("//Array.prototype[2] = \"hole10\";");
|
||||||
|
Array.prototype[2] = "hole10";
|
||||||
|
|
||||||
|
trace("//Array.prototype[3] = \"hole11\";");
|
||||||
|
Array.prototype[3] = "hole11";
|
||||||
|
|
||||||
|
trace("//Array.prototype[4] = \"hole12\";");
|
||||||
|
Array.prototype[4] = "hole12";
|
||||||
|
|
||||||
|
trace("//(properties of contents of a)");
|
||||||
|
assert_array_props(a);
|
||||||
|
|
||||||
|
trace("//(cleaning up our holes...)");
|
||||||
|
|
||||||
|
delete Array.prototype[2];
|
||||||
|
delete Array.prototype[4];
|
||||||
|
|
||||||
|
trace("//Array.prototype[3] = item4;");
|
||||||
|
Array.prototype[3] = item4;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("//var item1 = {\"numprop\": 3, \"strprop\": \"Abc\", \"numprop2\": 3}");
|
||||||
|
var item1 = {"numprop": 5, "strprop": "Abc", "numprop2": 3};
|
||||||
|
|
||||||
|
trace("//var item2 = {\"numprop\": 3, \"strprop\": \"Azc\", \"numprop2\": 2}");
|
||||||
|
var item2 = {"numprop": 3, "strprop": "Azc", "numprop2": 2};
|
||||||
|
|
||||||
|
trace("//var item3 = {\"numprop\": 3, \"strprop\": \"aXc\", \"numprop2\": 1}");
|
||||||
|
var item3 = {"numprop": 7, "strprop": "aXc", "numprop2": 1};
|
||||||
|
|
||||||
|
trace("//var item4 = {\"numprop\": 3, \"strprop\": \"boo\", \"numprop2\": 4}");
|
||||||
|
var item4 = {"numprop": 9, "strprop": "boo", "numprop2": 4};
|
||||||
|
|
||||||
|
trace("//var item5 = {\"numprop\": 5, \"strprop\": \"bool\", \"numprop2\": \"5\"}");
|
||||||
|
var item5 = {"numprop": 11, "strprop": "bool", "numprop2": "5"};
|
||||||
|
|
||||||
|
var a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//Array.prototype[3] = item4;");
|
||||||
|
Array.prototype[3] = item4;
|
||||||
|
|
||||||
|
trace("//a.sortOn(\"numprop\", Array.UNIQUESORT) === 0");
|
||||||
|
trace(a.sortOn("numprop", Array.UNIQUESORT) === 0);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.CASEINSENSITIVE | Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], Array.CASEINSENSITIVE))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.DESCENDING | Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], Array.DESCENDING))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], Array.DESCENDING));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.CASEINSENSITIVE | Array.DESCENDING | Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.DESCENDING | Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], Array.CASEINSENSITIVE | Array.DESCENDING))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.DESCENDING));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.NUMERIC | Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.NUMERIC | Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], Array.NUMERIC))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], Array.NUMERIC));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], Array.DESCENDING | Array.NUMERIC | Array.RETURNINDEXEDARRAY))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.NUMERIC | Array.RETURNINDEXEDARRAY));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], Array.DESCENDING | Array.NUMERIC))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.NUMERIC));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY, 0]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, 0]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [0, 0]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [0, 0]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY, Array.DESCENDING]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.DESCENDING]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [0, Array.DESCENDING]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [0, Array.DESCENDING]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, 0]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, 0]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [Array.DESCENDING, 0]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [Array.DESCENDING, 0]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [0, Array.CASEINSENSITIVE]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [0, Array.CASEINSENSITIVE]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, 0]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, 0]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [Array.CASEINSENSITIVE, 0]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE, 0]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE | Array.DESCENDING]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE | Array.DESCENDING]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [0, Array.CASEINSENSITIVE | Array.DESCENDING]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [0, Array.CASEINSENSITIVE | Array.DESCENDING]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE | Array.DESCENDING, 0]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE | Array.DESCENDING, 0]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [Array.CASEINSENSITIVE | Array.DESCENDING, 0]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE | Array.DESCENDING, 0]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, Array.CASEINSENSITIVE]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, Array.CASEINSENSITIVE]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [Array.DESCENDING, Array.CASEINSENSITIVE]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [Array.DESCENDING, Array.CASEINSENSITIVE]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//(contents of a.sortOn([\"numprop\", \"strprop\"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, Array.DESCENDING]))");
|
||||||
|
assert_array(a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, Array.DESCENDING]));
|
||||||
|
|
||||||
|
trace("//(properties of contents of a.sortOn([\"numprop\", \"strprop\"], [Array.CASEINSENSITIVE, Array.DESCENDING]))");
|
||||||
|
assert_array_props(a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE, Array.DESCENDING]));
|
||||||
|
test_holes(a);
|
||||||
|
|
||||||
|
a = fresh_array_a();
|
||||||
|
|
||||||
|
trace("//a.sortOn([\"strprop\", \"numprop\"], [Array.NUMERIC, Array.UNIQUESORT]) === 0");
|
||||||
|
trace(a.sortOn(["strprop", "numprop"], [Array.NUMERIC, Array.UNIQUESORT]) === 0);
|
|
@ -0,0 +1,539 @@
|
||||||
|
//var item1 = {"numprop": 3, "strprop": "Abc", "numprop2": 3}
|
||||||
|
//var item2 = {"numprop": 3, "strprop": "Azc", "numprop2": 2}
|
||||||
|
//var item3 = {"numprop": 3, "strprop": "aXc", "numprop2": 1}
|
||||||
|
//var item4 = {"numprop": 3, "strprop": "boo", "numprop2": 4}
|
||||||
|
//var item5 = {"numprop": 5, "strprop": "bool", "numprop2": "5"}
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//a.sortOn("numprop", Array.UNIQUESORT) === 0
|
||||||
|
false
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.RETURNINDEXEDARRAY))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.RETURNINDEXEDARRAY))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.RETURNINDEXEDARRAY))
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], Array.DESCENDING))
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.DESCENDING | Array.RETURNINDEXEDARRAY))
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], Array.CASEINSENSITIVE | Array.DESCENDING))
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.NUMERIC | Array.RETURNINDEXEDARRAY))
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], Array.NUMERIC))
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.NUMERIC | Array.RETURNINDEXEDARRAY))
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], Array.DESCENDING | Array.NUMERIC))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, 0]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [0, 0]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.DESCENDING]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [0, Array.DESCENDING]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, 0]))
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [Array.DESCENDING, 0]))
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [0, Array.CASEINSENSITIVE]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, 0]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE, 0]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY, Array.CASEINSENSITIVE | Array.DESCENDING]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [0, Array.CASEINSENSITIVE | Array.DESCENDING]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE | Array.DESCENDING, 0]))
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE | Array.DESCENDING, 0]))
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.DESCENDING, Array.CASEINSENSITIVE]))
|
||||||
|
3
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
4
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [Array.DESCENDING, Array.CASEINSENSITIVE]))
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//(contents of a.sortOn(["numprop", "strprop"], [Array.RETURNINDEXEDARRAY | Array.CASEINSENSITIVE, Array.DESCENDING]))
|
||||||
|
4
|
||||||
|
1
|
||||||
|
0
|
||||||
|
2
|
||||||
|
3
|
||||||
|
//(properties of contents of a.sortOn(["numprop", "strprop"], [Array.CASEINSENSITIVE, Array.DESCENDING]))
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//Array.prototype[2] = "hole10";
|
||||||
|
//Array.prototype[3] = "hole11";
|
||||||
|
//Array.prototype[4] = "hole12";
|
||||||
|
//(properties of contents of a)
|
||||||
|
11
|
||||||
|
bool
|
||||||
|
3
|
||||||
|
Azc
|
||||||
|
5
|
||||||
|
Abc
|
||||||
|
7
|
||||||
|
aXc
|
||||||
|
9
|
||||||
|
boo
|
||||||
|
//(cleaning up our holes...)
|
||||||
|
//Array.prototype[3] = item4;
|
||||||
|
//var a = new Array(item1, item2, item3)
|
||||||
|
//a[4] = item5;
|
||||||
|
//a.sortOn(["strprop", "numprop"], [Array.NUMERIC, Array.UNIQUESORT]) === 0
|
||||||
|
false
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue