Sort an array of objects?

M

Mark Smith

Hi,

If I have an array of objects such as:

[
0: {FirstName:Chris,LastName:Davidson}
1: {FirstName:Adam,LastName:McDonald}
2: {FirstName:John,LastName:Harvey}
3: {FirstName:Tom,LastName:Smith}
4: {FirstName:paul,LastName:Jones}
]

Does javascript provide a way to sort this array according to a given
field name?

If not, can you suggest a way to implement this?

Thanks,

Chris
 
M

Martin Honnen

Mark said:
If I have an array of objects such as:

[
0: {FirstName:Chris,LastName:Davidson}
1: {FirstName:Adam,LastName:McDonald}
2: {FirstName:John,LastName:Harvey}
3: {FirstName:Tom,LastName:Smith}
4: {FirstName:paul,LastName:Jones}
]

Is the above supposed to be Javascript syntax? I guess you want
var a =
[ { FirstName: "Chris", LastName: "Davidson" },
{ FirstName: "Adam", LastName: "McDonald" },
...
];
Does javascript provide a way to sort this array according to a given
field name?

There is a sort method on arrays that takes a comparison function as its
first and sole argument e.g
var a =
[ { FirstName: "Chris", LastName: "Davidson" },
{ FirstName: "Adam", LastName: "McDonald" },
{ FirstName: "John", LastName: "Harvey" },
{ FirstName: "Tom", LastName: "Smith" },
{ FirstName: "Paul", LastName: "Jones" }
];

a.sort(function(a, b) {
return a.LastName < b.LastName ? -1 :
a.LastName > b.LastName ? 1 : 0; });

alert(a[a.length - 1].LastName);
 
T

Tim Down

Hi,

If I have an array of objects such as:

[
 0: {FirstName:Chris,LastName:Davidson}
 1: {FirstName:Adam,LastName:McDonald}
 2: {FirstName:John,LastName:Harvey}
 3: {FirstName:Tom,LastName:Smith}
 4: {FirstName:paul,LastName:Jones}
]

Does javascript provide a way to sort this array according to a given
field name?

If not, can you suggest a way to implement this?

Thanks,

Chris

Your syntax has several errors: first, you seem to have got object and
array literal syntax mixed up; second, you've missed out commas
between the elements, and thirdly you haven't surrounded your strings
with quotes (single or double would do). What I presume you meant is
something like:

var names = [
{FirstName: "Chris", LastName: "Davidson"},
{FirstName: "Adam", LastName: "McDonald"},
{FirstName: "John", LastName: "Harvey"},
{FirstName: "Tom", LastName: "Smith"},
{FirstName: "Paul", LastName: "Jones"}
];

JavaScript arrays have a sort() method, which takes a comparison
function as its parameter. The Mozilla documentation covers this:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort

For your example, and assuming you wish to sort first by last name and
then by first name, the following will work:

names.sort(function(n1, n2) {
function compareStrings(s1, s2) {
return (s1 === s2) ? 0 : ( (s1 > s2) ? 1 : -1 );
}
return compareStrings(n1.LastName, n2.LastName) || compareStrings
(n1.FirstName, n2.FirstName);
});

Tim
 
B

Bart Van der Donck

Martin said:
Mark said:
[
 0: {FirstName:Chris,LastName:Davidson}
 1: {FirstName:Adam,LastName:McDonald}
 2: {FirstName:John,LastName:Harvey}
 3: {FirstName:Tom,LastName:Smith}
 4: {FirstName:paul,LastName:Jones}
]

Does javascript provide a way to sort this array according to a given
field name?

There is a sort method on arrays that takes a comparison function as its
first and sole argument e.g
   var a =
   [ { FirstName: "Chris", LastName: "Davidson" },
     { FirstName: "Adam", LastName: "McDonald" },
     { FirstName: "John", LastName: "Harvey" },
     { FirstName: "Tom", LastName: "Smith" },
     { FirstName: "Paul", LastName: "Jones" }
   ];

   a.sort(function(a, b) {
            return a.LastName < b.LastName ? -1 :
                                a.LastName > b.LastName ? 1 : 0; });

   alert(a[a.length - 1].LastName);

Alternatively

var s = new Array();
for (var i = 0; i < a.length; ++i) {
s = a.LastName;
}
alert(s.sort());
 
S

SAM

Le 6/29/09 1:30 PM, Mark Smith a écrit :
Hi,

If I have an array of objects such as:

var myData =
[
{FirstName:'Chris',LastName:'Davidson'},
{FirstName:'Adam', LastName:'McDonald'},
{FirstName:'John', LastName:'Harvey'},
{FirstName:'Tom', LastName:'Smith'},
{FirstName:'Paul', LastName:'Jones'}
];

No ?

(snip)
Does javascript provide a way to sort this array according to a given
field name?

array.sort(compareFunction);
here :
<https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort>


function ordering(myArray, fieldName) {
myArray.sort(function (obj1, obj2) {
return obj1[fieldName] < obj2[fieldName] ? -1 :
(obj1[fieldName] > obj2[fieldName] ? 1 : 0);
}
);
}

/** demo - sorting on last name **/

oedering(myData, 'LastName');

var t='';
for(var i=0; i<myData.length;i++)
t += myData.LastName+' - '+myData.FirstName+'\n';
alert(t);
 
T

Thomas 'PointedEars' Lahn

Bart said:
Martin said:
Mark said:
[
0: {FirstName:Chris,LastName:Davidson}
1: {FirstName:Adam,LastName:McDonald}
2: {FirstName:John,LastName:Harvey}
3: {FirstName:Tom,LastName:Smith}
4: {FirstName:paul,LastName:Jones}
]

Does javascript provide a way to sort this array according to a given
field name?
There is a sort method on arrays that takes a comparison function as its
first and sole argument e.g
var a =
[ { FirstName: "Chris", LastName: "Davidson" },
{ FirstName: "Adam", LastName: "McDonald" },
{ FirstName: "John", LastName: "Harvey" },
{ FirstName: "Tom", LastName: "Smith" },
{ FirstName: "Paul", LastName: "Jones" }
];

a.sort(function(a, b) {
return a.LastName < b.LastName ? -1 :
a.LastName > b.LastName ? 1 : 0; });

alert(a[a.length - 1].LastName);

Alternatively

var s = new Array();
for (var i = 0; i < a.length; ++i) {
s = a.LastName;
}
alert(s.sort());


This will yield a list of sorted last names (strings), if that (one SHOULD
NOT assume that Array.prototype.sort() returns a reference to the sorted
array, implementations differ here); so information will be lost. By
contrast, Martin's approach will result in the original array being sorted,
staying an array of Objects, which is what the OP asked for.


PointedEars
 
M

Matthias Reuter

Mark said:
If I have an array of objects such as:

[
0: {FirstName:Chris,LastName:Davidson}
1: {FirstName:Adam,LastName:McDonald}
2: {FirstName:John,LastName:Harvey}
3: {FirstName:Tom,LastName:Smith}
4: {FirstName:paul,LastName:Jones}
]

Well, that's not the right way to define an array in javascript. I removed
the index and added quotation marks.

[
{ FirstName: "Chris", LastName: "Davidson" },
{ FirstName: "Adam", LastName: "McDonald" },
{ FirstName: "John", LastName: "Harvey" },
{ FirstName: "Tom", LastName: "Smith" },
{ FirstName: "Paul", LastName: "Jones" }
]

Common practice was to write the keys starting with a lower case character.
Does javascript provide a way to sort this array according to a given
field name?

Not natively.
If not, can you suggest a way to implement this?

/*
* Returns a function that can be used as a compare
* function for the array's sort method
*
* Not a failsafe implementation, though.
*/
function sortByKey (key) {
return function (a, b) {
return a[key] < b[key];
};
}

arr.sort(sortByKey("LastName"));
arr.sort(sortByKey("FirstName"));
 
T

Thomas 'PointedEars' Lahn

Matthias said:
/*
* Returns a function that can be used as a compare
* function for the array's sort method
*
* Not a failsafe implementation, though.
*/
function sortByKey (key) {
return function (a, b) {
return a[key] < b[key];
};
}

arr.sort(sortByKey("LastName"));
arr.sort(sortByKey("FirstName"));

This will not work as expected (all examples should be tested before
posted). A comparator `c' is defined as follows:

{ -1 if a "<" b;
c := c(a, b) = { 1 if b "<" a;
{ 0 otherwise

By contrast, your comparators returns either `true' or `false'. You can
assume that `true' will be type-converted to 1, and `false' to 0, however
that would reverse the sort order and would be unnecessarily inefficient.
(Tested in Iceweasel/Firefox 3.0.11.)

In addition, suppose this was the intention, a two-pass sorting by different
property each will not result in an array that is sorted with both property
values as sort keys.


PointedEars
 
B

Bart Van der Donck

Thomas said:
Bart said:
  var s = new Array();
  for (var i = 0; i < a.length; ++i)  {
    s = a.LastName;
  }
  alert(s.sort());


This will yield a list of sorted last names (strings), if that (one SHOULD
NOT assume that Array.prototype.sort() returns a reference to the sorted
array, implementations differ here); so information will be lost.  By
contrast, Martin's approach will result in the original array being sorted,
staying an array of Objects, which is what the OP asked for.


I see both of your points; no much doubt about the latter; but the
docs encourage belief that 'aVAR = s.sort();' would be a spiritual
improvement rather than a real-world issue.
 
D

Dr J R Stockton

In comp.lang.javascript message <4d080598-b760-4a5e-8ade-b748d5fcc9a3@e2
1g2000yqb.googlegroups.com>, Mon, 29 Jun 2009 04:30:03, Mark Smith
Hi,

If I have an array of objects such as:

[
0: {FirstName:Chris,LastName:Davidson}
1: {FirstName:Adam,LastName:McDonald}
2: {FirstName:John,LastName:Harvey}
3: {FirstName:Tom,LastName:Smith}
4: {FirstName:paul,LastName:Jones}
]

Does javascript provide a way to sort this array according to a given
field name?

One wants to know when the field name will be given. One can write a
sort that uses the first name as a key, and one that uses the last name.
If only one of those is required, that's easiest.

Note : those are all Anglos. Don't forget that Chinese put
their names in the other order, and Mongolians (or similar)
only have one name.

That is, BTW, not how an array of objects is written.

Consider, for run-time selection of sort key,

Arr = [
{FirstName:'Chris',LastName:'Isaacson'},
{FirstName:'Adam',LastName:'McDonald'},
{FirstName:'John',LastName:'Harvey'},
{FirstName:'Tom',LastName:'Smith'},
{FirstName:'Paul',LastName:'Jones'} ]

function SF(A, B) { return (A[X]>B[X]) - (B[X]>A[X]) }

X = "LastName" // or "FirstName"

Z = Arr.sort(SF)[0].FirstName

which gives John // Adam

There is, no doubt, a more elegant way of passing X into SF; but it's
too late to think of that now.

To sort on one fixed key, replace [X] by .FirstName .

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top