【问题标题】:JSON iteration based on value using jquery使用 jquery 基于值的 JSON 迭代
【发布时间】:2015-02-22 19:34:24
【问题描述】:

我正在尝试使用以下 json 文件按种子顺序创建一个简单的 NBA 西部领袖显示:

http://data.nba.com/data/v2014/json/mobile_teams/nba/2014/00_standings.json

现在我有以下内容:

$(document).ready(function() {

$.getJSON('http://data.nba.com/data/v2014/json/mobile_teams/nba/2014/00_standings.json',function(info){

    var eastHead = info.sta.co[0].val;
    var divi = info.sta.co[0].di[0].val;

    /*evaluate East*/
    for(i=0;i < divi.length;i++){

        var visTeam ='<li>' + divi + '</li>';
         document.getElementById("eastHead").innerHTML=eastHead;
    }
    var seed = info.sta.co[0].di[0].t[0].see;


                    $.each(menuItems.data, function (i) {
                        var eastSeed ='<li>' + seed + '</li>';
                        console.log(eastSeed)
                        document.getElementById("eastSeed").innerHTML=eastSeed;
                    });//$.each(menuItems.data, function (i) {

});//getJSON

});//ready

我只想按顺序列出领导者。所以现在我们有

  1. 金州勇士队
    2. 孟菲斯队
    3. 休斯顿队
    4. 波特兰队
    5. 洛杉矶快船队
    6. 达拉斯队
    .... 等等 第四次。

这是基于“see”值,即西方的种子。

这个问题是我得到一个值而不是迭代。

更新:

$(document).ready(function() {

$.getJSON('http://data.nba.com/data/v2014/json/mobile_teams/nba/2014/00_standings.json',function(info){



                    /**************************************************/
                        //Get info above here
                        var westDivision = info.sta.co[1].di;
                        westDivision.forEach(function (subdivision)
                        {
                            subdivision.t.forEach(function (team)
                            {
                                westTeams.push({
                                    city: team.tc,
                                    name: team.tn,
                                    seed: team.see
                                });
                            });
                        });
                        function compare(a,b) {
                          if (a.see < b.see)
                             return -1;
                          if (a.see > b.see)
                            return 1;
                          return 0;
                        }
                        var sorted = westTeams.sort(compare);
                        sorted.forEach(function (el,i)
                        {
                            console.log(i+'. '+el.city+' '+el.name);
                        });
                        /**************************************************/    

});//getJSON

});//ready

控制台输出:

  1. 波特兰开拓者队
  2. 俄克拉荷马城雷霆队
  3. 丹佛掘金队
  4. 犹他爵士队
  5. 明尼苏达森林狼队
  6. 金州勇士队
  7. 洛杉矶快船队
  8. 凤凰太阳队
  9. 萨克拉门托国王队
  10. 洛杉矶湖人队
  11. 孟菲斯灰熊队
  12. 休斯顿火箭队
  13. 达拉斯小牛队
  14. 圣安东尼奥马刺队
  15. 新奥尔良鹈鹕队

【问题讨论】:

  • 我很好奇。你如何使用 Ajax 从他们的服务器中检索 NBA 统计数据?这对我不起作用(同源政策),我怀疑它对你有用。您的代码示例肯定行不通。

标签: javascript jquery json


【解决方案1】:

我喜欢使用 forEach 进行迭代。不必担心索引,您可以直接引用数组的每个项目。

使用此代码,您可以将所需的数据放入数组中。

//Get info above here
var westTeams = [];
var westDivision = info.sta.co[1].di;

westDivision.forEach(function (subdivision)
{
    subdivision.t.forEach(function (team)
    {
        westTeams.push({
            city: team.tc,
            name: team.tn,
            seed: team.see
        });
    });
});

然后你可以使用obj.sort对它们进行排序

function compare(a,b) {
  if (a.seed < b.seed)
     return -1;
  if (a.seed > b.seed)
    return 1;
  return 0;
}
var sorted = westTeams.sort(compare);

最后,你可以按顺序打印出来了。

sorted.forEach(function (el,i)
{
    console.log((i+1)+'. '+el.city+' '+el.name);
});

【讨论】:

  • 感谢您的回复。我得到了'westTeams is not defined'。不确定上面定义的现在引用的是什么?我已将更新后的脚本包含在原始消息中。
  • 抱歉,我不小心删除了定义该变量的行。它现在应该可以工作了。
  • 这很棒@J4G,但种子顺序不准确。我错过了什么吗?我已经包含了上面的输出。
  • 波特兰实际上是 0 而不是 1
  • 我无法发起聊天,但你可以,这样我们就可以深入讨论这个问题。只是为了让我明白这里发生了什么?我很困惑你对purhs做了什么。而且顺序还是不正确。
【解决方案2】:

查询大型 JavaScript 对象图可能是一件乏味的事情,尤其是当您想要动态输出时。实现对不同过滤条件、排序顺序、“前 N”限制、分页的支持可能很困难。而且你想出的任何东西往往都是不灵活的。

要涵盖这些情况,您可以(如果您不介意学习曲线)使用 linq.js (reference),这是一个实现 .NET 的 JavaScript LINQ 的库。

以下展示了您可以使用它做什么。长篇大论,请多多包涵。

准备

您的 NBA 数据对象遵循父子层次结构,但它遗漏了一些基本信息:

  • 没有parent 引用
  • 包含子项的属性在每个级别上的调用方式都不同(即codit

为了使整个事物统一(因此可遍历),我们首先需要从中构建一个节点树。树节点会包装输入图中的对象,如下所示:

{
    obj: o,       /* the original object, e.g. sta.co[1]               */
    parent: p,    /* the parent tree node, e.g. the one that wraps sta */
    children: []  /* array of tree nodes built from e.g. sta.co[1].di  */
}

这个结构的构建可以在一个函数中递归完成:

function toNode(obj) {
    var node = {
            obj: obj,
            parent: this === window ? null : this,
            // we're interested in certain child arrays, either of:
            children: obj.co || obj.di || obj.t || []
        };

    // recursive step (with reference to the parent node)
    node.children = node.children.map(toNode, node);

    // (*) explanation below
    node.parents = Enumerable.Return(node.parent)
        .CascadeDepthFirst("$ ? [$.parent] : []").TakeExceptLast(1);

    return node;
}

(*) node.parents 属性是一种便利设施。它包含除最后一个之外的所有父节点的枚举(即根节点,即null)。该枚举可用于过滤,如下所示。

这个函数的结果是一个漂亮而统一的节点树。 (展开代码sn-p,可惜由于同源浏览器限制,目前无法运行。可能NBA REST API中有些东西需要先开启。) p>

function toNode(obj) {
    var node = {
            obj: obj,
            parent: this === window ? null : this,
            children: obj.co || obj.di || obj.t || []
        };
    node.children = node.children.map(toNode, node);
    node.parents = Enumerable.Return(node.parent)
        .CascadeDepthFirst("$ ? [$.parent] : []").TakeExceptLast(1);
    return node;
}

$(function () {
    var standingsUrl = 'http://data.nba.com/data/v2014/json/mobile_teams/nba/2014/00_standings.json';
    $.getJSON(standingsUrl, function(result) {
        var sta = toNode(result.sta);
        console.log(sta);
    });
});
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

结果

现在我们有了一个完全可遍历的节点树,我们可以使用 LINQ 查询只用几行代码来完成复杂的事情:

// first build our enumerable stats tree
var stats = Enumerable.Return(toNode(result.sta));

// then traverse into children; the ones with a tid are teams
var teams = stats.CascadeDepthFirst("$.children")
    .Where("$.obj.tid");

好的,我们已经确定了所有团队,所以我们可以...

// ...select all that have a parent with val 'West' and order them by 'see'
var westernTeams = teams.Where(function (node) {
        return node.parents.Any("$.obj.val === 'West'");
    })
    .OrderByDescending("$.obj.see");

// ...insert the top 5 into our page as list items
westernTeams.Take(5).Do(function (node) {
    $("<li></li>", {text: node.obj.tc + ' ' + node.obj.tn}).appendTo("#topFiveList");
});

// ...turn them as an array of names
var names = westernTeams.Select("$.obj.tc + ' ' + $.obj.tn").ToArray();
console.log(names);

当然,我在几个步骤中所做的事情可以一步完成:

// request details for all Northwest and Southeast teams who have won more than one game (*)
var httpRequests = Enumerable.Return(toNode(result.sta))
    .CascadeDepthFirst("$.children")
    .Where("$.obj.tid")
    .Where(function (node) {
        var str = node.obj.str.split(" ");
        return str[0] === "W" && str[1] > 1 && 
            node.parents.Any("$.obj.val==='Northwest' || $.obj.val==='Southeast'");
    })
    .Select(function (node) {
        return $.getJSON(detailsUrl, {tid: node.obj.tid});
    })
    .ToArray();

$.when.apply($, httpRequests).done(function () {
    var results = [].slice.call(arguments);
    // all detail requests have been fetched, do sth. with the results
});

(*) 如果我错了,请纠正我,我不知道 JSON 文件中的数据实际上是什么意思

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-23
    • 2014-02-07
    • 1970-01-01
    • 2011-11-04
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    相关资源
    最近更新 更多