【问题标题】:localstorage: Get specific localstorage value of which contains many itemslocalstorage:获取包含多个项目的特定localstorage值
【发布时间】:2011-12-27 10:01:24
【问题描述】:

在本地存储中,我有关键的“results”与这个values

[{"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);
}

如何获取 item-3 或特定 ID 的 href?

【问题讨论】:

    标签: javascript jquery json local-storage stringify


    【解决方案1】:

    使用原生Array.filter

    如果您只针对现代浏览器(IE9+ 或任何其他主流浏览器的 recent version),您可以使用 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');
    

    Working example

    手动循环数据

    如果你不能使用过滤器,你可能会被困在只使用循环中:

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

    Working example

    尽管使用循环暴力破解它可能看起来不如使用Array.filter 优雅,但事实证明,在大多数情况下loop is faster than Array.filter

    重构为对象而不是数组

    最好的解决方案是重构您存储数据的方式,假设您的每个项目的id 是唯一的。使用使用id 作为键的对象来存储包含hreficon 键/属性值的对象,而不是对象数组。

    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;
    

    【讨论】:

    • 您好,谢谢。在我的使用中,我将 testItem 设置为 JSON.parse(localStorage.getItem("result"))。当我这样做时,所有结果都是未定义的。
    • 我真的不知道如何解释这一点,但我并没有像您那样设置所有值。我正在解析它们,然后在这两个示例中都没有定义。
    • @jQuerybeast 最初的示例只是设置测试数据,然后通过闭包访问它,我已将其更改为将其用作参数。然后你可以调用它来传递数据:testItem = getItemById(JSON.parse(localStorage.getItem("result")), 'item-3');。如果您需要获取多个项目,您可能应该将JSON.parse(localStorage.getItem("result")) 的结果分配给一个变量,而不是内联调用它。
    • @Hugolpz 您倾向于过多地更改答案。你改变了代码,你改变了意义。我永远不会批准这些编辑。不会因为这个而与你争吵,但我个人的建议是不要做这样的改变。随意修复语法和拼写,但让帖子作者修复代码或更改变量名称或其他任何东西。不要自己做。
    • @ShadowWizard:web 2.0。如果它是一个澄清,更好的澄清,更好的层次分割,更好的可读性:让我们去做吧。
    【解决方案2】:

    jQuery 有过滤器帮助器:

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

    具有特定 id 的项目的 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/ 上查看工作示例

    更新

    如果您无法从本地存储中读取项目,可能是您在设置值时忘记调用 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)

    This 是最后一个例子。

    编辑

    正如无用代码所指出的,这个方法比原生过滤器功能慢得多(和自定义循环,但我认为引入几行新代码来节省 20-30 毫秒是过度的,除非性能是一个问题),所以我更新我的示例以不使用 jquery 过滤器。 +1请他回答。

    另外,这里需要指出的重要一点是,如果这个数组有数百个而不是 8 个书签,那么从统计上来说,for 循环可能会快两倍(因为它不必遍历数组的其余部分)。但是,在这种情况下,将 for 循环放入返回第一个找到的满足条件的项目的函数中可能是个好主意,并且使用 prototypejs 它甚至可以连接到数组。

    【讨论】:

    • 我在哪里用哪一个?它似乎对我不起作用......而且它也没有任何意义。 getItemById 不是变量?
    • jQuery .filter() 方法用于过滤 DOM 节点,而不是 JSON 数据或数组。
    • @jQuerybeast 对不起,我的例子有缺陷,你需要调用我做的函数,而不是getItemById,我已经修复了例子,并添加了jsfiddle链接,这样你就可以看到用法了。
    • @Useless-code 来自您提供的链接:“过滤器描述:将匹配元素集减少为匹配选择器或通过函数测试的元素。”在这种情况下,匹配的元素集是 json 数组。没有什么可以阻止您使用它。
    • @GoranObradovic “匹配元素集”是指在创建 jQuery 对象时由选择器匹配的 DOM 元素。 jQuery 将接受非 DOM 对象,这是一种足够普遍的情况,您可以 使用它来过滤泛型数组,但它并不是真正意味着 来过滤泛型数组。无论如何,创建一个 jQuery 实例会产生很多不必要的开销。此方法比使用自定义循环慢得多,该循环在找到它正在搜索的项目或Array.prototype.filter() 时立即返回。这里的速度比较:jsfiddle.net/53v3G
    【解决方案3】:

    对于jquery的过滤方法,我觉得使用回调函数,并且绑定搜索参数更加优雅易读:

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

    da usual fiddle

    (但是,我更喜欢“for循环”方法”!)

    【讨论】:

      猜你喜欢
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多