views:

52

answers:

2

I have a pretty large number of objects "usrSession" I store them in my ArrayCollection usrSessionCollection.

I'M looking for a function that returns the latest userSessions added with a unique userID. So something like this:

1. search the usrSessionCollection and only return one userSessions per userID.

2. When it has returned x number of userSessions then deleted them from the usrSessionCollection

I'M stuck - would really love some code that can help me with that.

function ArrayCollection() {
    var myArray = new Array;
    return {
        empty: function () {
            myArray.splice(0, myArray.length);
        },
        add: function (myElement) {
            myArray.push(myElement);
        }
    }
}

function usrSession(userID, cords, color) {
    this.UserID = userID;
    this.Cords = cords;
    this.Color = color;
}

usrSessionCollection = new ArrayCollection();

$.getJSON(dataurl, function (data) {
    for (var x = 0; x < data.length; x++) {
        usrSessionCollection.add(new usrSession(data[x].usrID.toString(), data[x].usrcords.toString() ,data[x].color.toString());
    }
});

Thanks.

A: 

You made your array private, so you can't access the data, except adding a new element or removing them all. You need to make the array public, or provide a public interface to access the data. Like first(), next() or item(index).

Then you can add a search(userID) method to the usrSessionCollection, which uses this interface to go through the elements and search by userID.


UPDATE: this is how I would do it: - See it in action. (click preview)

// user session
function userSession(userID, cords, color) {
    this.UserID = userID;
    this.Cords = cords;
    this.Color = color;
}

// a collection of user sessionions
// a decorated array basically, with
// tons of great methods available
var userSessionCollection = Array;

userSessionCollection.prototype.lastById = function( userID ) {
  for ( var i = this.length; i--; ) {
    if ( this[i].UserID === userID ) {
      return this[i];
    }
  }
  // NOTE: returns undefined by default
  // which is good. means: no match
};

// we can have aliases for basic functions
userSessionCollection.prototype.add = Array.prototype.push;

// or make new ones
userSessionCollection.prototype.empty = function() {
  return this.splice(0, this.length);
};

//////////////////////////////////////////////////////

// make a new collection
var coll = new userSessionCollection();

// put elements in (push and add are also available)
coll.add ( new userSession(134, [112, 443], "#fffff") );
coll.push( new userSession(23,  [32,  -32], "#fe233") );
coll.push( new userSession(324, [1,    53], "#ddddd") );


// search by id (custom method)
var search = coll.lastById(134);
if( search ) {
  console.log(search.UserID);
} else {
  console.log("there is no match");
}


// empty and search again
coll.empty();
search = coll.lastById(134);
if( search ) {
  console.log(search.UserID);
} else {
  console.log("there is no match");
}
galambalazs
I was hoping for some more specific help with the search/remove from array functionality.
seo20
you can search an array by going trough it, but **if the data is hidden** for the outside **and there is no interface, you can't access it**. You came from a class based language btw? Your code seems to be a little bit overcomplicated for the task.
galambalazs
+2  A: 

The biggest issue is that you have made the array private to the outside world. Only methods through which the array can be interacted with are add and empty. To be able to search the array, you need to either add that functionality in the returned object, or expose the array. Here is a modified ArrayCollection:

function ArrayCollection() {
    var myArray = new Array;
    return {
        empty: function () {
            myArray.splice(0, myArray.length);
        },
        add: function (myElement) {
            myArray.push(myElement);
        },
        getAll: function() {
            return myArray;
        }   
    }
}

Now to get the last N unique session objects in usrSessionCollection, traverse the sessions array backwards. Maintain a hash of all userID's seen so far, so if a repeated userID comes along, that can be ignored. Once you've collected N such user sessions or reached the beginning of the array, return all collected sessions.

usrSessionCollection.getLast = function(n) {
    var sessions = this.getAll();
    var uniqueSessions = [];
    var addedUserIDs = {}, session, count, userID;

    for(var i = sessions.length - 1; i >= 0, uniqueSessions.length < n; i--) {
        session = sessions[i];
        userID = session.userID;

        if(!addedUserIDs[userID]) {
            uniqueSessions.push(session);
            addedUserIDs[userID] = true;
        }
    }

    return uniqueSessions;
}

I wouldn't combine the delete step with the traversal step, just to keep things simple. So here's the remove method that removes the given session from the array. Again, it's better to modify the interface returned by ArrayCollection rather than tampering with the sessions array directly.

function ArrayCollection(..) {
    return {
        ..,
        remove: function(item) {
            for(var i = 0; i < myArray.length; i++) {
                if(item == myArray[i]) {
                    return myArray.splice(i, 1);
                }
            }
            return null;
        }
    };
}

Example: Get the last 10 unique sessions and delete them:

var sessions = usrSessionCollection.getLast(10);
for(var i = 0; i < sessions.length; i++) {
    console.log(sessions[i].UserID); // don't need dummy variable, log directly
    usrSessionCollection.remove(sessions[i]);
}

See a working example.

Anurag
So when I'M using my sessions I do something like this:var sessions = usrSessionCollection.getLast(2); for (var i = 0; i < sessions.length; i++) { var p = new usrSession("", "", ""); p = sessions[i]; console.log(p.UserID); usrSessionCollection.remove(sessions[i]); }?
seo20
@seo20 What is the point of creating a dummy session object `p`, and then discarding it immediately? What are you trying to do here? You can log contents of `sessions[i]` directly without using a temporary variable. Even if using a temporary variable, don't create a `usrSession` object needlessly. Instead, directly assign `sessions[i]` to that temp variable. Example - `var session = sessions[i]; alert(session.UserID);` Updated answer too.
Anurag
Awesome thanks a lot
seo20
@seo20 You're welcome. I'm glad it helped.
Anurag