高级搜索/队列数组收集问题

时间:2010-06-30 22:50:38

标签: javascript jquery collections queue

我有大量的对象“usrSession”我将它们存储在我的ArrayCollection usrSessionCollection中。

我正在寻找一个函数,它返回添加了唯一userID的最新userSession。所以像这样:

1。 搜索usrSessionCollection,每个用户ID只返回一个userSessions。

2。 当它返回x个userSessions然后从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 个答案:

答案 0 :(得分:2)

最大的问题是你已经将数组专用于外部世界。只有通过其可以与数组进行交互的方法是addempty。为了能够搜索数组,您需要在返回的对象中添加该功能,或者公开数组。这是经过修改的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;
        }   
    }
}

现在要在usrSessionCollection中获取最后N个唯一会话对象,向后遍历会话数组。保持到目前为止看到的所有userID的哈希值,因此如果出现重复的userID,则可以忽略该哈希值。收集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;
}

我不会将删除步骤与遍历步骤结合起来,只是为了简单起见。所以这是remove方法从数组中删除给定的会话。同样,最好修改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]);
}

查看working example

答案 1 :(得分:0)

您将数组设为私有,因此除了添加新元素或将其全部删除外,您无法访问数据。您需要将数组设置为public,或者提供公共接口来访问数据。像first(),next()或item(index)。

然后,您可以向usrSessionCollection添加搜索(userID)方法,该方法使用此接口遍历元素并按用户ID进行搜索。


更新:我就是这样做的: - See it in action。 (点击预览)

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