将JSON数组与jQuery相结合

Combining JSON Arrays with jQuery

本文关键字:jQuery 相结合 数组 JSON      更新时间:2024-06-09

我花了一上午的时间来处理这个问题,并在这里阅读,但我发现自己在兜圈子!

我正在尝试使用优秀的AmCharts Javascript图表绘制一张图表,将股票持有量显示为条形图,将股票转向显示为折线图。

我无法从一个查询中获得两组数据到我的数据库,也无法使用AmCharts StockChart,因为它不是基于时间的数据。。。因此,我有两组数据需要与Javascript相结合。

数据是从数据库中提取的,并以类似于以下的JSON数组成功返回:

销售数据:

[{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
 {"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
 {"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}]

股票数据:

[{"brandName":"Gibson","stockValue":"1234"},
 {"brandName":"Fender","stockValue":"975"},
 {"brandName":"Epiphone","stockValue":"834"}]

很明显,这个例子中的实际数字是虚构的!

现在,我需要做的是将这些结合起来创建这个:

组合数据

[{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55","stockValue":"975"},
 {"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43","stockValue":"1234"},
 {"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13","stockValue":"834"}]

我们有一个销售数据集和库存数据集,将stockValue的额外数据添加到相应的brandName记录中。

我试过使用$.extend,但我不知道如何在这种情况下使用它。

也许需要注意的是,数据对的顺序可能不一定正确,而且可能(尽管可能性不大)不匹配,因此必须实现某种归零错误捕获。

首先需要做的是将数据转换为两个对象,它们的属性是要合并在一起的值:

{
"Fender" : {"gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
"Gibson" : {"gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
"Epiphone" : {"gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}
}

{
"Gibson": {"stockValue":"1234"},
"Fender": { "stockValue":"975"},
"Epiphone": { "stockValue":"834"}
}

转换完成后,您将有两个对象,可以使用$.extend或其他函数进行合并。

更新

对于大型集合,这在几乎线性的时间内给出结果:

var salesa = {}, stocka = {};
$.each(sales, function(i, e) {
    salesa[e.brandName] = e;
});
$.each(stock, function(i, e) {
    stocka[e.brandName] = e;
});
var combine = {};
$.extend(true, combine, salesa, stocka)

如果合并发生在第二次转换回调($each(stock...)期间,而不是单独调用$.extend(),则可以调整更高的速度,但它会失去一些明显性。

我想他想做的是把两个数据集连接起来,就像它们是表一样,用brandName连接。从我测试的情况来看,jQuery的$.extend()函数并没有考虑到这一点,而是根据对象在它接收的对象数组中的索引合并对象。

我认为钥匙的匹配需要手动完成。

stock = [{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
 {"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
 {"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}];
value = [{"brandName":"Gibson","stockValue":"1234"},
 {"brandName":"Fender","stockValue":"975"},
 {"brandName":"Epiphone","stockValue":"834"}];
var results = [];
$(stock).each(function(){
    datum1 = this;
    $(value).each(function() {
        datum2 = this;
        if(datum1.brandName == datum2.brandName)
            results.push($.extend({}, datum1, datum2));
    });
});

这将导致:

[{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55","stockValue":"975"},
{"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43","stockValue":"1234"},
{"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13","stockValue":"834"}]

使用$.extend()返回的不是什么:

[{"brandName":"Gibson","gearShiftedPerMonth":"35","retailSalesPerMonth":"55","stockValue":"1234"},
{"brandName":"Fender","gearShiftedPerMonth":"23","retailSalesPerMonth":"43","stockValue":"975"},
{"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13","stockValue":"834"}]

如果您的示例代码反映了现实,那么jQuery的$.extend将是错误的工具。

它盲目地将数据从一个对象复制到另一个对象。请注意,数据的顺序不一致。SALES DATA首先具有Fender,而STOCK DATA首先具有gibson

所以jQuery的$.extend混合了这两个结果。Fender的"gearShifted"answers"retailSales"以Gibson的"brandName"answers"stockValue"结束。


您需要的是迭代一个数组,在另一个数组中查找"brandName",然后复制所需的数据。如果你愿意的话,你可以使用$.extend来完成这部分。。。

var sales_data = 
[{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
 {"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
 {"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}]
var stock_data = 
[{"brandName":"Gibson","stockValue":"1234"},
 {"brandName":"Fender","stockValue":"975"},
 {"brandName":"Epiphone","stockValue":"834"}]
var combined = $.map(sales_data, function(obj, i) {
    return $.extend({}, obj, $.grep(stock_data, function(stock_obj) {
        return obj.brandName === stock_obj.brandName
    })[0]);
});

请注意,这不是很有效,但除非数据集很大,否则这不应该是一个问题


演示:http://jsfiddle.net/sDyKx/

结果:

[
    {
        "brandName": "Fender",
        "gearShiftedPerMonth": "35",
        "retailSalesPerMonth": "55",
        "stockValue": "975"
    },
    {
        "brandName": "Gibson",
        "gearShiftedPerMonth": "23",
        "retailSalesPerMonth": "43",
        "stockValue": "1234"
    },
    {
        "brandName": "Epiphone",
        "gearShiftedPerMonth": "10",
        "retailSalesPerMonth": "13",
        "stockValue": "834"
    }
]

在普通javascript中,您可以执行:

var sales = [{"brandName":"Fender","gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
 {"brandName":"Gibson","gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
 {"brandName":"Epiphone","gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}];
var stock = [{"brandName":"Gibson","stockValue":"1234"},
 {"brandName":"Fender","stockValue":"975"},
 {"brandName":"Epiphone","stockValue":"834"}];
var combined = stock.slice(0);     
for (var i = 0; i < stock.length; i++) {
    for (var j = 0; j < sales.length; j++) {
        if (stock[i].brandName === sales[j].brandName) {
            for (var attrname in sales[j]) { combined[i][attrname] = sales[j][attrname]; }
        }
    }
}
JSON.stringify(combined)

产生

[
{"brandName":"Gibson","stockValue":"1234","gearShiftedPerMonth":"23","retailSalesPerMonth":"43"},
{"brandName":"Fender","stockValue":"975","gearShiftedPerMonth":"35","retailSalesPerMonth":"55"},
{"brandName":"Epiphone","stockValue":"834","gearShiftedPerMonth":"10","retailSalesPerMonth":"13"}
]