简体   繁体   English

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

[英]How do I index by multiple items in an Array or Object using JavaScript/jQuery?

Background 背景

I have an Array of data in a result object returned by an Ajax call. 我在Ajax调用返回的结果对象中有一个数据Array。 The data looks like this: 数据如下所示:

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

Where each item looks like this: 每个项目看起来像这样:

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

Question

I want to be able to retrieve data either by Id (returning a single user) or by Title (returning an array of users). 我希望能够通过Id (返回单个用户)或Title (返回用户数组)来检索数据。 What would be the best way to go about doing that using JavaScript or jQuery? 使用JavaScript jQuery进行此操作的最佳方法是什么?

Example

Here's what I've attempted so far: 这是我到目前为止所做的尝试:

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

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

The code I have above is great for indexing by Id, but I'm not sure what to do for Title. 我上面的代码很适合用Id编制索引,但我不知道该怎么做Title。

Additional Details 额外细节

Also, by the way, there are about 1000 records , and I need this to be fairly efficient . 顺便说一下,大约有1000条记录 ,我需要这个记录才能相当高效 (This is one of the reasons I'm getting the data right away, when the document is ready. I'm not an expert on JavaScript or jQuery efficiency, though. Let me know if you have a better way.) (这是我在文档准备就绪时立即获取数据的原因之一。但我不是JavaScript或jQuery效率方面的专家。如果你有更好的方法,请告诉我。)

Any ideas? 有任何想法吗? Thanks in advance! 提前致谢!

Seems like you're looking for .grep() . 好像你在寻找.grep() Using .grep you could create a generic function that would filter: 使用.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");

Create a constructor function vis-à-vis class that encapsulates this data, and you can ask it to find users by title, or id. 创建一个构造函数,相对于封装此数据的类,您可以要求它按标题或ID查找用户。 To do a quick lookup, you can create two lookup tables - one for id, and another for title. 要进行快速查找,您可以创建两个查找表 - 一个用于id,另一个用于标题。 Assuming a decent hash implementation, the lookups can be done in O(1) on the average. 假设一个合适的散列实现,查找可以平均在O(1)完成。 The initial computation is O(n), but lookups are faster. 初始计算是O(n),但查找速度更快。 Also it uses slightly more space because we are creating two additional maps. 它还使用了更多的空间,因为我们正在创建两个额外的地图。 For 1000 objects, that is not a problem. 对于1000个对象,这不是问题。 Again, if you will be doing a lot more lookups, this approach will be much faster. 同样,如果您要进行更多查找,这种方法会更快。

Here's a simple implementation. 这是一个简单的实现。

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

To use it, create an object of Users passing it the AJAX response, and then query it using the findById and findByTitle methods. 要使用它,请创建一个Users对象,向其传递AJAX响应,然后使用findByIdfindByTitle方法进行查询。

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

Checkout a working example . 查看一个工作示例

I think this should work. 我认为这应该有效。 I really can't test it without your data. 没有你的数据,我真的无法测试它。

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


    }
});
}

If you have control over the data returned, it's better if you produce it with the following format: 如果您可以控制返回的数据,那么使用以下格式生成数据会更好:

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

This way you avoid the loop ( $(result).each() ) inside GetAllUsers (which builds the array above). 这样就可以避免GetAllUsers (构建上面的数组)中的循环( $(result).each() )。 The search by title can be performed efficiently by building a second array of the form: 可以通过构建表单的第二个数组来有效地执行按title搜索:

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

As you see, each title has a list of indexes to allUsers . 如您所见,每个标题都有一个allUsers的索引列表。 Then you simply do: 然后你只需:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM