【问题标题】:How to separate JSON array into 2 separate arrays of values with jQuery?如何使用 jQuery 将 JSON 数组分成 2 个单独的值数组?
【发布时间】:2016-09-14 22:23:32
【问题描述】:

我有以下 AJAX 脚本从 PHP 文件中提取 JSON 数组:

// get jsonData from inc/wip-data.php
var jsonData = $.ajax({
  url: 'inc/wip-data.php',
  dataType: 'json',
});

JSON数组如下:

[
{
    "date": "2015-10",
    "clientCostsTotal": "0.00"
},
{
    "date": "2015-11",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-01",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-02",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-03",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-04",
    "clientCostsTotal": "27962.50"
},
{
    "date": "2016-05",
    "clientCostsTotal": "174060.00"
},
{
    "date": "2016-06",
    "clientCostsTotal": "309000.00"
},
{
    "date": "2016-07",
    "clientCostsTotal": "502261.50"
},
{
    "date": "2016-08",
    "clientCostsTotal": "7598.00"
},
{
    "date": "2016-12",
    "clientCostsTotal": "0.00"
}
]

我需要获取所有date 值并将它们存储在一个数组中。此外,我需要获取所有 clientCostsTotal 值并将它们存储在单独的数组中。我该怎么做?

感谢您的帮助。

【问题讨论】:

  • JSON,对于您的对象数组,有几个 array methods 可以做到这一点,但请尝试对每个所需的新数组使用 Array#map。 jQuery也有类似的方法。

标签: javascript jquery arrays json ajax


【解决方案1】:

不需要jQuery,像这样使用Array.forEach()

var dates = [];
var clientCosts = [];

$.ajax({
  url: 'inc/wip-data.php',
  dataType: 'json'
}).done(function(data) {
  data.forEach(function(item) {
    dates.push(item.date);
    clientCosts.push(item.clientCostsTotal);
  });
});

对于更实用的方法,您可能想尝试使用Array.reduce(),它使您能够生成多个结果数组,同时仍然只对源数据进行一次迭代。这是一个使用.reduce() 实现的函数,它将采用您拥有的任何结构的数组并将这些结果整理成一个结果。此函数是通用的,适用于源中定义的任何属性名称。

function collate(d) {
  return d.reduce(function(prev, cur, index) {
    var ret = {};
    for (var prop in cur) {
      if (index === 0) {
        ret[prop] = [];
      } else {
        ret[prop] = prev[prop];
      }
      ret[prop].push(cur[prop]);
    }
    return ret;
  }, {});
}

var data = [{
  "date": "2015-10",
  "clientCostsTotal": "0.00"
}, {
  "date": "2015-11",
  "clientCostsTotal": "0.00"
}, {
  "date": "2016-01",
  "clientCostsTotal": "0.00"
}, {
  "date": "2016-02",
  "clientCostsTotal": "0.00"
}, {
  "date": "2016-03",
  "clientCostsTotal": "0.00"
}, {
  "date": "2016-04",
  "clientCostsTotal": "27962.50"
}, {
  "date": "2016-05",
  "clientCostsTotal": "174060.00"
}, {
  "date": "2016-06",
  "clientCostsTotal": "309000.00"
}, {
  "date": "2016-07",
  "clientCostsTotal": "502261.50"
}, {
  "date": "2016-08",
  "clientCostsTotal": "7598.00"
}, {
  "date": "2016-12",
  "clientCostsTotal": "0.00"
}];

var reduced = collate(data);
console.log(reduced.date, reduced.clientCostsTotal);

【讨论】:

  • 我在jsonData.forEach(function(item) { 收到一个控制台错误,上面写着“charts-test.php:443 Uncaught TypeError: jsonData.forEach is not a function”。我该如何解决这个问题?
  • 数据返回后,您是否在回调中使用该函数?还是在数据到达之前立即调用函数?
  • 您的 AJAX 调用实际上不是返回 JSON,而是返回 jQuery jqXHR 对象。您需要在编辑后的答案中添加.done() 回调。
  • 我认为之前有一个额外的逗号,请参阅更新。
  • 完美运行。感谢您的帮助@dave
【解决方案2】:

为什么不使用.map?它将不必分配一个全新的数组并推送到它?

$.ajax({
  url: 'inc/wip-data.php',
  dataType: 'json',
}).done(function(data) {
  // One for dates
  var dates = data.map(function(item) {
    return item.date;
  });

  // The other for client costs
  var clientCostTotals = data.map(function(item) {
    return item.clientCostsTotal;
  });
});

【讨论】:

  • 因为结果只创建一个数组,而不是两个
  • 好地方。已更新。
  • 这行得通,但现在您将数组循环两次而不是一次。 forEach() 或简单的循环更适合这种情况。
  • 我认为不会。两个原因。首先,这里的代码比使用forEach() 更实用。我不需要转发任何东西,因此维护更容易。我也没有使阵列静音。其次,在现代浏览器中,当循环服务器返回的数组时,您永远不会注意到任何性能下降。你唯一会拥有一个微不足道的数组。在这种情况下,我更喜欢可读性更高的代码。 map()forEach() IMO 提供的更多。
  • 好吧,关于设置和维护,我可以同意你的看法,但我不愿意把性能抛到脑后。也许最好的解决方案是使用Array.reduce() 的实现,它保留了.map() 的功能设计,但也避免了源数据的重复迭代。
【解决方案3】:

jQuery解决方案

// Your data will look like
var dataArrayOfJson = [{"date": "2015-10", "clientCostsTotal": "0.00"},{"date": "2015-11","clientCostsTotal": "0.00"}];

var dates = [], clientCostsTotals= [];
$(dataArrayOfJson ).each( function(i,item){ 
  dates.push(dataArrayOfJson [i].date);  // or dates.push(item.date);
  clientCostsTotals.push(dataArrayOfJson [i].clientCostsTotal); // or  clientCostsTotals.push(item.clientCostsTotal);
});

【讨论】:

  • 我在dates.push(data[i].date); // or dates.push(item.date); 收到一个控制台错误,上面写着“charts-test.php:445 Uncaught ReferenceError: data is not defined”。我该如何解决这个问题?
  • 抱歉更新示例正在使用不同的变量名进行测试data
【解决方案4】:

我一直在使用的一个新解决方案是map 函数。它是为函数式编程而开发的,一种更好的分割“树”的方法,并且更易于理解。仍在学习,但我推荐这个视频here。 ECMA 5 完全支持它。

var Array1 = 
[
{
    "date": "2015-10",
    "clientCostsTotal": "0.00"
},
{
    "date": "2015-11",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-01",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-02",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-03",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-04",
    "clientCostsTotal": "27962.50"
},
{
    "date": "2016-05",
    "clientCostsTotal": "174060.00"
},
{
    "date": "2016-06",
    "clientCostsTotal": "309000.00"
},
{
    "date": "2016-07",
    "clientCostsTotal": "502261.50"
},
{
    "date": "2016-08",
    "clientCostsTotal": "7598.00"
},
{
    "date": "2016-12",
    "clientCostsTotal": "0.00"
}];

var result = Array1.map(function(a) {
var dates = [], clientCostsTotals= [];
dates.push(a.date); 
clientCostsTotals.push(a.clientCostsTotal);
});

希望对你有帮助!

【讨论】:

  • 我认为您需要再次阅读Array#map 文档。
  • 如果函数中没有return 语句,那么使用.map() 有什么意义? result 将充满 undefined 值。
  • 如果不返回任何东西,还不如直接使用.forEach()
【解决方案5】:

我的偏好是使用 lodash 进行涉及数组的操作。 lodash api has a function called map 很好地满足您的要求。这是一个例子:

var jsonArray = [
{
    "date": "2015-10",
    "clientCostsTotal": "0.00"
},
{
    "date": "2015-11",
    "clientCostsTotal": "0.00"
},
{
    "date": "2016-01",
    "clientCostsTotal": "0.00"
}];
var dateValues = _.map(jsonArray, 'date');
var clientTotalCostValues = _.map(jsonArray, 'clientCostsTotal');
console.log('dateValues = ', dateValues);
console.log('clientTotalCostValues = ', clientTotalCostValues );

输出以下内容:

dateValues =  ["2015-10", "2015-11", "2016-01"]
clientTotalCostValues =  ["0.00", "0.00", "0.00"]

您可以通过转到lodash api docs page 打开浏览器开发工具并将我的代码 sn-p 粘贴到控制台并按 Enter 来快速测试它。

【讨论】:

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