【问题标题】:json sibling datajson兄弟数据
【发布时间】:2012-10-24 02:33:24
【问题描述】:

(如果我使用了稍微不正确的语言,请原谅我 - 请随时根据需要进行建设性的更正)

有几篇关于从返回对象中的兄弟姐妹的 JSON 数据中获取数据的帖子,但我无法将这些信息应用于我的情况:

我有一堆对象从 REST 调用中以 JSON 形式返回,并且对于每个具有特定键节点的对象:值我需要提取特定键的兄弟节点的数值。例如:

对于以下对象列表,我需要将每个具有匹配“desc”的对象的“file_size”中的数字相加,并将其返回到页面上匹配的输入值。

{"ResultSet":{

  Result":[

    {
        "file_size":"722694",
        "desc":"description1",
        "format":"GIF"
    },

    {
        "file_size":"19754932",
        "desc":"description1",
        "format":"JPEG"
    },

    {
        "file_size":"778174",
        "desc":"description2",
        "format":"GIF"
    },

    {
        "file_size":"244569996",
        "desc":"description1",
        "format":"PNG"
    },

    {
        "file_size":"466918",
        "desc":"description2",
        "format":"TIFF"
    }

  ]

}}

【问题讨论】:

    标签: javascript jquery ajax json


    【解决方案1】:

    您可以使用以下功能:

    function findSum(description, array) {
        var i = 0;
        var sum = 0;
    
        for(i = 0; i < array.length; i++) {
            if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
                sum += parseInt(array[i]["file_size"], 10);
            }
        }
    
        alert(sum);
    }
    

    然后这样称呼它:

    findSum("description1", ResultSet.Result);
    

    显示包含所有 "description1" 文件大小总和的警报。

    一个工作的 JSFiddle 在这里:http://jsfiddle.net/Q9n2U/


    作为对您的更新和 cmets 的回应,这里有一些新代码创建了一些 divs 以及所有描述的总和。我取出了hasOwnProperty 代码,因为您更改了数据集,但请注意如果数据数组中有没有file_size 属性的对象,则必须使用hasOwnProperty 进行检查 .你应该可以很容易地为你的 jQuery .each 调整它。

    var data = {};
    var array = ResultSet.Result;
    
    var i = 0;
    var currentDesc, currentSize;
    var sizeDiv;
    var sumItem;
    
    //Sum the sizes for each description
    for(i = 0; i < array.length; i++) {
        currentDesc = array[i]["desc"];
        currentSize = parseInt(array[i]["file_size"], 10);
    
        data[currentDesc] =
            typeof data[currentDesc] === "undefined"
            ? currentSize
            : data[currentDesc] + currentSize;
    }
    
    //Print the summations to divs on the page
    for(sumItem in data) {
        if(data.hasOwnProperty(sumItem)) {
            sizeDiv = document.createElement("div");
            sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
            document.body.appendChild(sizeDiv);
        }
    }
    

    一个工作的 JSFiddle 在这里:http://jsfiddle.net/DxCLu/

    【讨论】:

    • 这个很近。如何在循环时已经用于执行其他操作的 jQuery $.each 函数中调用它?我将如何返回结果以用于为每个“desc”类型创建唯一的 DOM 元素?
    • 这个有效。你能解释一下代码: data[currentDesc] = typeof data[currentDesc] === "undefined" 吗? currentSize : 数据[currentDesc] + currentSize;我只是想知道我自己的理解发生了什么。
    • 数据[currentDesc] = typeof data[currentDesc] === "undefined" ? currentSize : 数据[currentDesc] + currentSize;它是 if/else 的简写吗?
    • 还有一个问题。我已更新代码以在原始数组中包含另一个项目 - 我如何显示每个“desc”的每个“格式”的总数,例如:description1: 444MB (222MB JPEG, 222MB GIF)?
    • @mflorida:我正在使用ternary (or conditional) operator,正如您所建议的,它类似于 if/else 语句。当你说你有另一个问题时,这是一个很好的例子,说明何时创建另一个全新的问题是一个好主意,正如我之前提到的那样。通过这种方式,您可以从许多不同的人那里获得帮助,而不仅仅是一个人。
    【解决方案2】:

    这是一个嵌入在对象中的数组,所以

    data.ResultSet.Result[2].file_size
    

    会给你778174

    【讨论】:

    • 你只需对数组进行循环,找到你想要的,然后加起来。
    • 我需要为每个“desc”写出每个总计的结果,并且“真实”数据中至少有 10 个不同的“desc”值。就像:如果“desc”匹配“description1”,则将所有值相加并存储在隐藏的输入字段中,然后如果“desc”匹配“description2”,则执行相同操作。听起来我将不得不为每个来自服务器的“desc”值循环,这意味着找到这些值,将它们存储在一个新数组中,然后检查数组中的每个项目的“desc”值"。
    • 每个返回的数据集可能有数百个数组中的项目,并且可能有几十个数据集要返回,所以我宁愿不必为“desc”的每个值循环。我不能将每个“desc”值的值存储在一个数组中,然后将它们加在一起吗?如何为每个“desc”创建单独的数组并告诉 javascript 只输入匹配项?
    【解决方案3】:
    var sum = {}, result = ResultSet.Result
    
    // Initialize Sum Storage
    for(var i = 0; i < result.length; i++) {
      sum[result[i].desc] = 0; 
    }
    
    // Sum the matching file size
    for(var i = 0; i < result.length; i++) {
      sum[result[i].desc] += parseInt(result[i]["file_size"]
    }
    

    执行上述代码后,您将拥有一个名为sum 的JSON,如下所示

    sum = {
      "description1": 20477629,
      "description2": 1246092
    };
    

    【讨论】:

    • if( result[i].desc in sum ) sum[result[i].desc] += parseInt(result[i]["file_size"]; else sum[result[i].desc] = parseInt(result[i]["file_size"]; 一站式循环。
    • 啊……这有帮助。如果我已经在 ResultSet.Result 中,有没有办法做到这一点?就用“这个”?
    【解决方案4】:

    像下面这样的迭代应该可以完成这项工作,

    var result =  data.ResultSet.Result;
    var stat = {};
    for (var i = 0; i < result.length; i++) {    
        if (stat.hasOwnProperty(result[i].cat_desc)) {       
            if (result[i].hasOwnProperty('file_size')) {
            stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);   
            }
        } else {
            stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
        }   
    }
    

    演示: http://jsfiddle.net/HtrLu/1/

    【讨论】:

    • 在代码中使用 'hasOwnProperty' 我已经可以解决问题了!谢谢!
    • 所以“hasOwnProperty”告诉我该属性是否存在(我知道它会在我得到的 JSON 中) - 那么我如何获取/匹配该特定属性的值?
    • @mflorida 你所说的匹配是什么意思.. 只需在对象上使用[]. .. 比如data['file_size']data.file_size
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2019-07-25
    • 2018-10-03
    • 2022-11-18
    相关资源
    最近更新 更多