【问题标题】:How do I index by multiple items in an Array or Object using JavaScript/jQuery?如何使用 JavaScript/jQuery 按数组或对象中的多个项目进行索引?
【发布时间】:2012-03-06 05:24:21
【问题描述】:

背景

我在 Ajax 调用返回的结果对象中有一个数据数组。数据如下所示:

{ Name="User1 Name1", FirstName="User1", Id="005400000001234567", more...}
{ Name="User2 Name1", FirstName="User2", Id="005400000001234568", more...}

每个项目如下所示:

{
    Id:"005400000001234567",
    Name:"User Name",
    FirstName:"User",
    LastName:"Name",
    Title:"Manager"
}

问题

我希望能够通过 Id(返回单个用户)或 Title(返回一组用户)检索数据。使用 JavaScript jQuery 的最佳方法是什么?

示例

到目前为止,这是我尝试过的:

function GetAllUsers()
{
    AllUsersById = new Object();

    MyClass.MyAjaxMethod(function(result,event) {
        if(result) { 
            j$(result).each(function(index,item)
            {
                AllUsersById[item.Id] = item;
            });
        }
    });
}

我上面的代码非常适合按 Id 进行索引,但我不确定要为 Title 做什么。

其他详情

另外,顺便说一下,大约有 1000 条记录,我需要这样做相当高效。 (这是我在文档准备好后立即获取数据的原因之一。不过,我不是 JavaScript 或 jQuery 效率方面的专家。如果您有更好的方法,请告诉我。)

有什么想法吗?提前致谢!

【问题讨论】:

  • 您是否需要将其全部设为一个数组,或者您可以构建两个 - 一个用于按 # 索引,一个用于按标题分组。

标签: javascript jquery ajax arrays object


【解决方案1】:

您似乎在寻找.grep()。使用 .grep 您可以创建一个可以过滤的通用函数:

function findInJson (json, key, value) {
    return $.grep(json, function (obj) {
        return obj[key] == value;
    });
}

// With your data getting a specific user by id
findInJson(yourJSON, "Id", "005400000001234567");

// Getting a set of users by title
findInJson(yourJSON, "Title", "Manager");

【讨论】:

  • 我在 jQuery 参考中注意到“$.grep() 方法根据需要从数组中删除项目,以便所有剩余项目通过提供的测试。” grep 是否真的修改了它正在搜索的数组?
  • @MatthewKeefe grep 不会更改您正在搜索的对象。
【解决方案2】:

创建一个构造函数 vis-à-vis 封装这些数据的类,您可以要求它按标题或 id 查找用户。要进行快速查找,您可以创建两个查找表 - 一个用于 id,另一个用于标题。假设一个不错的哈希实现,查找可以在O(1) 中完成。初始计算为 O(n),但查找速度更快。它还使用了更多的空间,因为我们正在创建两个额外的地图。对于 1000 个对象,这不是问题。同样,如果您要进行更多查找,这种方法会更快。

这是一个简单的实现。

function Users(users) {
    this.idMap = {};
    this.titleMap = {};
    this.users = users;
    var me = this;

    users.forEach(function(user) {
        this.idMap[user.Id] = this.idMap[user.Id] || [];
        this.idMap[user.Id].push(user);

        this.titleMap[user.Title] = this.titleMap[user.Title] || [];
        this.titleMap[user.Title].push(user);
    }.bind(this));
}

Users.prototype.findByTitle = function(title) {
    return this.titleMap[title];
};

Users.prototype.findById = function(id) {
    return this.idMap[id];
};

要使用它,请创建一个 Users 的对象,将 AJAX 响应传递给它,然后使用 findByIdfindByTitle 方法对其进行查询。

var users = new Users(responseData);
users.findById("1");
users.findByTitle("SomeTitle");

检查一个有效的example

【讨论】:

  • 令人着迷。我从您的回答和示例中学到了很多东西,谢谢!但是,为了简单起见,我认为我必须使用 grep
【解决方案3】:

如果您可以控制返回的数据,最好使用以下格式生成它:

var allUsers=[
{"005400000001234567":{
    Name:"User Name",
    FirstName:"User",
    LastName:"Name",`
    Title:"Manager"
}} 
,{"005400000001234568":{
    Name:"User2 Name2",
    FirstName:"User2",
    LastName:"Name2",
    Title:"Manager2"
}} 
/*..etc.. */
];

这样可以避免GetAllUsers 内部的循环($(result).each())(它构建了上面的数组)。 title 的搜索可以通过构建表单的第二个数组来有效地执行:

var byTitle=["title1":[0,1], "title1":[0,1], /*etc*/];

如您所见,每个标题都有一个指向allUsers 的索引列表。然后你只需这样做:

var allManagers = [];
for(var i in byTitle["Manager"]) allManagers.push(allUsers[i]);

【讨论】:

    【解决方案4】:

    我认为这应该可行。没有你的数据我真的无法测试。

    function GetAllUsers()
    {
    
    AllUsersById = new Object();
    AllUsersByType = new Object();
    
    MyClass.MyAjaxMethod(function(result,event) {
        if(result) { 
            j$(result).each(function(index,item)
            {
                // By Id
                AllUsersById[item.Id] = item;
    
                // By Type
                if (!AllUsersByTitle[item.Title]) {
                    AllUsersByTitle[item.Title] = new Array();
                }
    
                AllUsersByType[item.type].push() = item;
            });
    
    
        }
    });
    }
    

    【讨论】:

    • 当我在第一个 each 循环中将它们全部组合在一起并在 push 之前添加:if (!AllUsersByTitle[item.Title]) { AllUsersByTitle[item.Title] = new Array(); } 时,您的第一个示例有效。
    猜你喜欢
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 2018-07-07
    • 2011-07-27
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多