localstorage: получить конкретное значение localalstorage, которое содержит много элементов - PullRequest
2 голосов
/ 12 ноября 2011

В местном хранилище у меня есть ключ ' результаты ' с этими значениями :

[{"id":"item-1","href":"google.com","icon":"google.com"},
{"id":"item-2","href":"youtube.com","icon":"youtube.com"},
{"id":"item-3","href":"google.com","icon":"google.com"},
{"id":"item-4","href":"google.com","icon":"google.com"},
{"id":"item-5","href":"youtube.com","icon":"youtube.com"},
{"id":"item-6","href":"asos.com","icon":"asos.com"},
{"id":"item-7","href":"google.com","icon":"google.com"},
{"id":"item-8","href":"mcdonalds.com","icon":"mcdonalds.com"}]

Чтобы получить последний элемент, я использую это:

// this is how I parse the arrays
var result = JSON.parse(localStorage.getItem("result")); 


for(var i=0;i<result.length;i++) {
    var item = result[i];
    $('element').val(item.href);
}

Как я могу получить href для элемента-3 или для определенного идентификатора?

Ответы [ 3 ]

8 голосов
/ 12 ноября 2011

Использование собственного Array.filter

Если вы ориентируетесь только на современные браузеры (IE9 + или последняя версия любого другого основного браузера), вы можете использовать метод массива JavaScript 1.6 filter.

var testItem,
    data = [{"id":"item-1","href":"google.com","icon":"google.com"},
{"id":"item-2","href":"youtube.com","icon":"youtube.com"},
{"id":"item-3","href":"google.com","icon":"google.com"},
{"id":"item-4","href":"google.com","icon":"google.com"},
{"id":"item-5","href":"youtube.com","icon":"youtube.com"},
{"id":"item-6","href":"asos.com","icon":"asos.com"},
{"id":"item-7","href":"google.com","icon":"google.com"},
{"id":"item-8","href":"mcdonalds.com","icon":"mcdonalds.com"}];

function getItemById(data, id) {
    // filter array down to only the item that has the id
    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
    var ret = data.filter(function (item) {
        return item.id === id;
    });

    // Return the first item from the filtered array   
    // returns undefined if item was not found
    return ret[0];
}


testItem = getItemById(data, 'item-3');

Рабочий пример

Зацикливание данных вручную

Если вы не можете использовать фильтр, вы используетевероятно, застрял с использованием только цикла:

var testItem,
    data = [{"id":"item-1","href":"google.com","icon":"google.com"},
{"id":"item-2","href":"youtube.com","icon":"youtube.com"},
{"id":"item-3","href":"google.com","icon":"google.com"},
{"id":"item-4","href":"google.com","icon":"google.com"},
{"id":"item-5","href":"youtube.com","icon":"youtube.com"},
{"id":"item-6","href":"asos.com","icon":"asos.com"},
{"id":"item-7","href":"google.com","icon":"google.com"},
{"id":"item-8","href":"mcdonalds.com","icon":"mcdonalds.com"}];

function getItemById(data, id) {
    var i, len;
    for (i = 0, len = data.length; i < len; i += 1) {
        if(id === data[i].id) {
            return data[i];
        }
    }

    return undefined;
}

testItem = getItemById(data, 'item-3');

Рабочий пример

Даже если перебор с помощью цикла может показаться менее элегантным, чем использование Array.filter,получается, что в большинстве случаев цикл работает быстрее, чем Array.filter.

Рефакторинг к объекту вместо массива

Лучшее решение, предполагая, что id каждого из ваших предметов уникальны, это будет рефакторинг того, как вы храните данные.Вместо массива объектов используйте объект, который использует id в качестве ключа для хранения объекта, содержащего значения ключа / свойства href и icon.

var data = {
    "item-1": {"href": "google.com", "icon": "google.com"},
    "item-2": {"href": "youtube.com", "icon": "youtube.com"},
    "item-3": {"href": "google.com", "icon": "google.com"},
    "item-4": {"href": "google.com", "icon": "google.com"},
    "item-5": {"href": "youtube.com", "icon": "youtube.com"},
    "item-6": {"href": "asos.com", "icon": "asos.com"},
    "item-7": {"href": "google.com", "icon": "google.com"},
    "item-8": {"href": "mcdonalds.com", "icon": "mcdonalds.com"}
};

Это приведет к доступупредметы еще проще и быстрее:

var data = JSON.parse(localStorage.getItem("result")); 
data["item-3"].href;
1 голос
/ 12 ноября 2011

В jQuery есть фильтр-помощник:

$(result).filter(function(){return this.id == "item-3";})[0]

Функция для href элемента с определенным идентификатором будет:

function getItemHrefById(json, itemId){
    return json.filter(function(testItem){return testItem.id == itemId;})[0].href;
}

И пример использования:

var href = getItemHrefById(result, "item-3");

Вы можете увидеть рабочий пример на http://jsfiddle.net/LXvLB/

UPDATE

Если вы не можете прочитать элемент из локального хранилища, возможно, вы забыли вызвать JSON.stringify при установке значения:

localStorage["results"] = JSON.stringify([{"id":"item-1","href":"google.com","icon":"google.com"}, 
{"id":"item-2","href":"youtube.com","icon":"youtube.com"}, 
{"id":"item-3","href":"google.com","icon":"google.com"}, 
{"id":"item-4","href":"google.com","icon":"google.com"}, 
{"id":"item-5","href":"youtube.com","icon":"youtube.com"}, 
{"id":"item-6","href":"asos.com","icon":"asos.com"}, 
{"id":"item-7","href":"google.com","icon":"google.com"}, 
{"id":"item-8","href":"mcdonalds.com","icon":"mcdonalds.com"}])

Вам необходимо преобразовать json в строку, чтобы правильно сериализовать (и использовать JSON.parse, чтобы вернуть JSON)

Это последний пример.

EDIT

Как указывал «Бесполезный код», этот метод существенно медленнее, чем встроенная функция фильтра (и пользовательский цикл, но я думаю, что введение нескольких новых строк кода для экономии 20-30 мс является излишним, если производительность не является проблемой), поэтому я Обновление моего примера, чтобы не использовать фильтр jquery. +1 пожалуйста за ответ за это.

Кроме того, на что важно обратить внимание, если этот массив будет иметь сотни, а не 8 закладок, цикл for, вероятно, будет статистически примерно в два раза быстрее (поскольку он не должен выполнять итерации по остальной части массива). Но в этом случае, вероятно, было бы неплохо поместить цикл for в функцию, которая возвращает первый найденный элемент, который удовлетворяет условию, и с помощью prototypejs он, вероятно, даже может быть подключен к массиву.

0 голосов
/ 12 ноября 2011

для метода фильтра jquery, я думаю, что использование функции обратного вызова и связывание параметра поиска более элегантно и читабельно:

function filterById(id, i, obj) {
    return obj.id === id;
}

function getItemHrefById(json, itemId) {
    return $(json).filter(filterById.bind(null, itemId))[0].href;
}

да обычная скрипка

(однако я предпочитаю подход "для цикла" для этого !!)

...