如何使用 JavaScript/jQuery 按数组或对象中的多个项目进行索引?

Posted

技术标签:

【中文标题】如何使用 JavaScript/jQuery 按数组或对象中的多个项目进行索引?【英文标题】:How do I index by multiple items in an Array or Object using 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 效率方面的专家。如果您有更好的方法,请告诉我。)

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

【问题讨论】:

您是否需要将其全部设为一个数组,或者您可以构建两个 - 一个用于按 # 索引,一个用于按标题分组。 【参考方案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(); 时,您的第一个示例有效。

以上是关于如何使用 JavaScript/jQuery 按数组或对象中的多个项目进行索引?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript/JQuery 创建一个简单的地图 [重复]

如何使用 Javascript/jQuery 确定图像是不是已加载?

如何使用 Javascript/jQuery 确定图像是不是已加载?

如何使用 PHP 或 JavaScript/jQuery 禁用地址栏?

Rails如何检测是不是使用javascript / jQuery插入了部分

如何使用 javascript/jquery 编写 onshow 事件?