Расширенный поиск / вопрос коллекции массива очереди - PullRequest
0 голосов
/ 01 июля 2010

У меня довольно большое количество объектов "usrSession". Я храню их в своей коллекции ArrayCollection usrSessionCollection.

Я ищу функцию, которая возвращает последние пользовательские сессии, добавленные с уникальным идентификатором пользователя. Вот как то так:

1. выполнить поиск в usrSessionCollection и вернуть только одну userSessions для userID.

2. Когда он вернул x количество пользовательских сеансов, то удалил их из коллекции usrSessionCollection

Я застрял - очень хотелось бы некоторый код, который может помочь мне в этом.

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());
    }
});

Спасибо.

Ответы [ 2 ]

2 голосов
/ 01 июля 2010

Самая большая проблема в том, что вы сделали массив закрытым для внешнего мира. Только методы, с которыми можно взаимодействовать с массивом, это add и empty. Чтобы иметь возможность поиска в массиве, вам нужно либо добавить эту функциональность в возвращаемый объект, либо выставить массив. Вот модифицированный 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;
        }   
    }
}

Теперь, чтобы получить последние N уникальных объектов сеанса в usrSessionCollection, просмотрите массив сеансов в обратном направлении. Сохраняйте хеш всех идентификаторов пользователя, увиденных до сих пор, поэтому, если появляется повторяющийся идентификатор пользователя, это можно игнорировать. Как только вы собрали N таких пользовательских сессий или достигли начала массива, верните все собранные сессии.

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;
}

Я бы не совмещал шаг удаления с шагом обхода, просто для простоты. Итак, вот метод удаления, который удаляет данный сеанс из массива. Опять же, лучше изменить интерфейс, возвращаемый ArrayCollection, чем напрямую вмешиваться в массив сессий.

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;
        }
    };
}

Пример: получить последние 10 уникальных сеансов и удалить их:

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]);
}

См. рабочий пример .

0 голосов
/ 01 июля 2010

Вы сделали свой массив приватным, поэтому вы не можете получить доступ к данным, кроме как добавив новый элемент или удалив их все. Вам необходимо сделать массив открытым или предоставить открытый интерфейс для доступа к данным. Как first (), next () или item (index).

Затем вы можете добавить метод поиска (userID) к usrSessionCollection, который использует этот интерфейс для просмотра элементов и поиска по userID.


ОБНОВЛЕНИЕ: Вот как я бы это сделал: - Смотрите это в действии (нажмите превью)

// 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");
}
...