10

Background

I have an array of objects (Users) defined and set as follows:

// object definition
function Users()
{
  this.Id = null;
  this.Name = null;
  this.FirstName = null;
  this.LastName = null;
  this.IsActive = null;
  this.Title = null;
  this.index = null;
  this.selected = null;
}

// object array
var AllUsers = [];

// ...
// an ajax call retrieves the Users and adds them to the AllUsers array
// ...

The index value is set on each User to the order in which they were retrieved. Once the Users are retrieved, they can then be selected, one-by-one, and moved from a list to a table on the page. Upon select, the selected property is set to true, for the selected object in the array.

I'm using grep to return all of the selected Users.

var SelectedUsers = $.grep(AllUsers,function(obj){
  return obj["selected"] == true;
});

Here's an example of the data returned:

[ 
  Object { 
    Id="00540000001AbCdEFG", 
    Name="First Last1", 
    FirstName="First", 
    LastName="Last1", 
    Title="Title", 
    index=56, 
    selected=true 
  },
  Object { 
    Id="00540000001AbChIJK", 
    Name="First Last2", 
    FirstName="First", 
    LastName="Last2", 
    Title="Title", 
    index=12, 
    selected=true 
  },
  Object { 
    Id="00540000001AbClMNO", 
    Name="First Last3", 
    FirstName="First", 
    LastName="Last3", 
    Title="Title", 
    index=92, 
    selected=true 
  }
]

Question

I want to be able to page through the data, and to do that, I need to be able to get the next and previous selected User by index. How can I do that?

If, for example, I open the first Selected User (index=56), in the table, how can I get the User with the next index (the third Selected User with index=92)?

JSFiddle

4
  • 3
    +1 for nicely explained question as well as fiddle Commented Jun 20, 2012 at 16:23
  • 1
    It seems like you will have to either sort or rearrange the array to fit your needs; if the array is small, it should efficient enough to iterate through all the elements to index them differently. Commented Jun 20, 2012 at 16:29
  • @Mahn no need to do that, sort() function is enough. Commented Jun 20, 2012 at 16:35
  • 2
    Thanks OP. $.grep is a new one to me. Commented Jun 20, 2012 at 16:37

3 Answers 3

3

Fiddle: http://jsfiddle.net/iambriansreed/KEXwM/

JavaScript Added:

SelectedUsers.sort(function(a,b){
      return a.index == b.index ? 0 : (a.index < b.index ? -1 : 1)});

If you didn't want to modify the original SelectedUsers array then define the sort to a new variable:

var SortedSelectedUsers = SelectedUsers.slice(0);
SortedSelectedUsers.sort(function(a,b){
      return a.index == b.index ? 0 : (a.index < b.index ? -1 : 1)});
Sign up to request clarification or add additional context in comments.

8 Comments

Array.sort() sorts the array in place. The original array is always modified. See this test example: jsfiddle.net/jfriend00/VPnFz
sort always modifies the array, copying the reference won't help.
Thanks @jfriend00 and Bergi - fixed it.
Using slice(0) to clone the array might preserve the original.
Why use return a.index == b.index ? 0 : (a.index < b.index ? -1 : 1)}); when return(a.index - b.index) is simpler?
|
3

Why not just sort your array by index?

allUsers.sort(function(a, b) {
    return(a.index - b.index);
});

Then, the next selected user would be the next user in the array that was selected. You could just walk up the array until you found a selected user.

Or, you could use your grep function to get all the selected users and then sort that by index so the next selected user would just be the next one in the selectedUsers array like this:

var SelectedUsers = j$.grep(AllUsers,function(obj){
  return obj["selected"] == true;
}).sort(function(a, b) {
    return(a.index - b.index);
});

2 Comments

-1 Wouldn't sorting allUsers be unnecessary as he only needs to sort the SelectedUsers.
@iambriansreed - I offer both options and the OP can decide which fits their needs better. It might be easier to just have the keep the main array sorted rather than resort everytime you do a grep - it depends upon what other operations are being done on it and what else the main array is used for.
2

Implement your own sorting function by index:

function compareUsers(a,b)
{
    return (a.index - b.index);
}

And sort the objects:

SelectedUsers.sort(compareUsers);

Now you have all the indexes in the correct order. From this, it's easy to get the following or preceding object by index number.

2 Comments

-1 As I was reminded in my answer's comments, you are creating two sorted arrays here: SortedUsers and SelectedUsers;
@iambriansreed You're absolutely right, sort() works directly on the array. I'm going to fix my answer, thanks for pointing out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.