Array sorting by reference

3 views
Skip to first unread message

Brett Zamir

unread,
Nov 30, 2009, 4:02:26 AM11/30/09
to ph...@googlegroups.com
As discussed at
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/0568e4abfc40a935?
(if you're interested in all the details), we can't assume any more than
we can sort our arrays by reference; we will have to either:

1) Reimplement the functions to return a copy of a sorted array (unlike PHP)
2) Or, force associative arrays to be built in this form:


// This could be, for example, handled inside an alternate
implementation of array() (which might also accept a single object
literal to build the array wrapper), but we wouldn't know if they meant
to build an associative array or an actual series of objects
var obj = array({"name1":'value1'}, {"name2":'value2'});
obj._ = {}; // This extra layer lets us use numeric indices
obj._["name1"] = obj[0];
obj._["name2"] = obj[1];

Besides not being able to use object literals directly (unless passed
into array() perhaps), this would require cumbersome access (e.g.,
obj._.name1) and even more cumbersome, though potentially wrappable,
modifications.

I think the simpler solution is therefore #1: reimplement the array
sorting functions to return a copy of the sorted array, though we could
also have a configuration option for those of us working in a non-IE
environment like Firefox extensions.

It's really a pity, but, as per the thread, but with this deletion of
properties being remembered, there's no apparent way to get Explorer to
reorder existing properties by reference.




Brett

unread,
Dec 4, 2009, 9:26:10 AM12/4/09
to php.js
On Nov 30, 5:02 pm, Brett Zamir <bret...@gmail.com> wrote:
> As discussed athttp://groups.google.com/group/comp.lang.javascript/browse_thread/thr...
I really feel I should fix these questions quickly--either to return
the array (contrary to PHP) or indicate that it will only work with
Mozilla and other browsers. Actually, I could make a special
"Mozilla" (or "Gang of Four" for Mozilla,Google, Safari, and Opera?)
ini setting for setting the behavior to work in non-IE environments
but return the array by default.

But I want to act on this one quickly because we have a good handful
of common array functions which use this and people could really be
misled into thinking it will work for IE (as one person already
revealed for us that it doesn't). This one is such a disappointment--
I hope IE and the future ES specs can fix the iteration order and
everything it entails.

Theriault

unread,
Dec 4, 2009, 2:25:06 PM12/4/09
to php.js
Doesn't this also mean that array_pop, array_push, array_shift,
array_unshift, and array_splice are broken in IE? How would these
return a copy of the array when the return values of these functions
are expected to be the extracted elements or the new length? Or by
"return," did you mean replace the original with the new copy?

I think I'm leaning towards #1, regardless. IE has a huge market share
and people could end up spending hours debugging this problem if they
didn't read the fine print. I see more problems occurring with not
having it act the way it's expected to act than replacing the original
with a copy (which is also not acting the way it's expected to act,
but less severe in my eyes).
> everything it entails.- Hide quoted text -
>
> - Show quoted text -

Kevin van Zonneveld

unread,
Dec 13, 2009, 10:31:17 AM12/13/09
to ph...@googlegroups.com
Rhino also doesn't remember the order of objects. At least up until
1.7. That caused the tester to mess up htmlspecialchar functions,
cause the order in which to encode/decode is important (or else: & may
become: &amp;amp;)
I had always thought this was limited to rhino but apparently not.

I really dislike the wrapping everything. It will make all array
functions dependent and probably a lot slower as well. I would hate
for php.js to turn that way.

Theriault makes a good point. With array_shift it's just not possible
to return the modified array(object). So with #1 we're going to have
to add 'fine print' anyway, warning that IE users will have a
array_shift implementation that looks nothing like PHP's original
(cause we're returning both [item, modiefied_object] or sth).

I understand from the topic that shredding the original var and
replacing it with a copy will not work. I'd like to examine that a
little further cause it would be the lightweight solution.

If that really doesn't work, with no shredding algorithm we can come
up with, there really is no pretty solution it seems.
--
Met vriendelijke groet / Kind regards,

Kevin van Zonneveld
http://kevin.vanzonneveld.net

http://twitter.com/kvz

Brett Zamir

unread,
Dec 16, 2009, 11:43:27 PM12/16/09
to ph...@googlegroups.com, Theriault
Sorry for the very delayed reply...

On 12/5/2009 3:25 AM, Theriault wrote:
> Doesn't this also mean that array_pop, array_push, array_shift,
> array_unshift, and array_splice are broken in IE?

Yes, it would--but fortunately I suppose, only array_pop() and
array_splice() even made an attempt to support associative arrays.

array_pop() is kind of ok (at least with the fix I made just now) since
IE at least iterates in order, though I put a warning there (and in
array_splice()).

I added functionality in array_push() for associative arrays, again with
a disclaimer.

I still need to get array_shift() and array_unshift() to work,
renumbering keys as in PHP (similar to how it is done in array_splice()
though I need to check my work there too), and will need to add a
warning there too.


> How would these
> return a copy of the array when the return values of these functions
> are expected to be the extracted elements or the new length? Or by
> "return," did you mean replace the original with the new copy?
>

I think for these we should just recommend against use of the functions
for associative arrays unless in a non-IE environment. The functions
should still work as expected for genuine arrays.

> I think I'm leaning towards #1 [Doing non-PHP way of returning copy], regardless. IE has a huge market share


> and people could end up spending hours debugging this problem if they
> didn't read the fine print. I see more problems occurring with not
> having it act the way it's expected to act than replacing the original
> with a copy (which is also not acting the way it's expected to act,
> but less severe in my eyes).
>

Yeah... I've also added support for the other way though if one is in a
non-IE environment (like FF extensions), but it requires an ini_set()
call...

best wishes,
Brett

Brett Zamir

unread,
Dec 16, 2009, 11:58:14 PM12/16/09
to ph...@googlegroups.com, Kevin van Zonneveld
On 12/13/2009 11:31 PM, Kevin van Zonneveld wrote:
> Rhino also doesn't remember the order of objects. At least up until
> 1.7. That caused the tester to mess up htmlspecialchar functions,
> cause the order in which to encode/decode is important (or else:& may
> become:&amp;amp;)
> I had always thought this was limited to rhino but apparently not.
>
>
Well, IE fortunately does iterate in order--it's just that you can't
truly delete properties, as their order is remembered.

Although ECMAScript allows implementation-dependent behavior for
iteration, most implementations do at least iterate in order, although
IE has the additional caveat (which doesn't concern us too much since we
should filter with hasOwnProperty() and not expect extended objects)
that it iterates in the opposite order for properties on the prototype.

See
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/0568e4abfc40a935?
for more details...

> I really dislike the wrapping everything. It will make all array
> functions dependent and probably a lot slower as well. I would hate
> for php.js to turn that way.
>

Sure, though it can be done with some optimizations (see also the
thread). If we required people use "array()) to wrap their arrays, it
could be more doable that way.

> Theriault makes a good point. With array_shift it's just not possible
> to return the modified array(object). So with #1 we're going to have
> to add 'fine print' anyway, warning that IE users will have a
> array_shift implementation that looks nothing like PHP's original
> (cause we're returning both [item, modiefied_object] or sth).
>
>

We previously didn't support objects at all, though I've added that
support except for array_shift() and array_unshift() (which I hope to do
soon if I get some time), but warned against their use in IE. I think
that will be less ugly in these cases then returning both (and they
still can use the functions with real arrays). Though I guess we could
add another configuration mode which allows both to be returned. Thoughts?

> I understand from the topic that shredding the original var and
> replacing it with a copy will not work. I'd like to examine that a
> little further cause it would be the lightweight solution.
>

No, that is not possible, unless we require the array name to be passed
in as a string and then reach out on the object, though that requires
that the input array be a global (kind of like we were forced to do with
settype()). So, that wouldn't work very well.

Brett

Kevin van Zonneveld

unread,
Jan 26, 2010, 5:54:52 AM1/26/10
to ph...@googlegroups.com
Let's settle with the warning for IE users ok?

--

Brett Zamir

unread,
Jan 26, 2010, 9:15:55 PM1/26/10
to ph...@googlegroups.com, Kevin van Zonneveld
Yeah... We still need array_shift() and array_unshift() to work with
objects (for the sake of non-IE environments), but there's a note about
that. I think I can use some code from array_splice for that, but I
think there may be a bug to work out with it too...

Also, we still need array_multisort() (Theriault?) to be fixed to work
with the configuration of returning the sorted array by default unless
"phpjs.strictForIn" ini is configured otherwise, though there's a bit of
a note there now about it....

Brett

Reply all
Reply to author
Forward
0 new messages