Как мне индексировать по нескольким элементам в массиве или объекте, используя JavaScript / jQuery? - PullRequest
6 голосов
/ 15 февраля 2012

Фон

У меня есть массив данных в объекте результата, возвращенном вызовом 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, но я не уверен, что делать с заголовком.

Дополнительные детали

Кроме того, кстати, есть около 1000 записей , и мне нужно, чтобы это было довольно эффективно . (Это одна из причин, по которой я получаю данные сразу же, когда документ готов. Однако я не эксперт по эффективности JavaScript или jQuery. Дайте мне знать, если у вас есть лучший способ.)

Есть идеи? Заранее спасибо!

Ответы [ 4 ]

5 голосов
/ 15 февраля 2012

Похоже, вы ищете .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");
2 голосов
/ 15 февраля 2012

Создайте функцию конструктора по отношению к классу, который инкапсулирует эти данные, и вы можете попросить ее найти пользователей по названию или идентификатору.Для быстрого поиска вы можете создать две таблицы поиска - одну для идентификатора, а другую для заголовка.Предполагая приличную реализацию хэша, поиск может быть выполнен в среднем за 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, а затем запросите его, используя методы findById и findByTitle.

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

Оформление рабочего примера .

0 голосов
/ 15 февраля 2012

Если у вас есть контроль над возвращенными данными, лучше, если вы создадите их в следующем формате:

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

Таким образом, вы избегаете цикла ($(result).each()) внутри GetAllUsers (который строит массив выше). Поиск по title может быть эффективно выполнен путем создания второго массива вида:

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

Как видите, у каждого заголовка есть список индексов allUsers. Тогда вы просто делаете:

var allManagers = [];
for(var i in byTitle["Manager"]) allManagers.push(allUsers[i]);
0 голосов
/ 15 февраля 2012

Я думаю, что это должно работать. Я действительно не могу проверить это без твоих данных.

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


    }
});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...