0

我正在尝试重写 d3.js 提供的示例。原始代码具有这样的功能:

function interpolateValues(values, year) {
var i = bisect.left(values, year, 0, values.length - 1),
    a = values[i];
if (i > 0) {
  var b = values[i - 1],
      t = (year - a[0]) / (b[0] - a[0]);
  return a[1] * (1 - t) + b[1] * t;
}
return a[1];
}

其中 'values' 是一个如下所示的数组:

"income":[[1800,359.93],[1820,359.93],[1913,556.12],[1950,3363.02], etc.

但是,我们以不同的方式存储数据。与 "name":[[year,value]],... 格式不同,我们的数据以不同的方式存储,很像数据库(示例数据如下):

{"region":"A","income":1178.0,"lifeExpectancy":788.0,"year":1800.0,"population":1292.0,"country":"Angola"},
{"region":"B","income":847.0,"lifeExpectancy":1183.0,"year":1800.0,"population":803.0,"country":"Benin"},
{"region":"A","income":798.0,"lifeExpectancy":765.0,"year":1801.0,"population":967.0,"country":"Angola"},
{"region":"B","income":1293.0,"lifeExpectancy":1497.0,"year":1801.0,"population":792.0,"country":"Benin"},

我正在寻找一个不同的函数替换 interpolateValues() 函数,如下所示:

SELECT income FROM dataset WHERE year = 1980

我知道这是 SQL,我只是用它来尝试理解这个想法。基本上你有一个包含数据的数组,一个包含年份的数组,我正在寻找一个返回特定年份数据的函数。

插值功能很不错,但目前还不是很重要。问题是我只是在学习使用 js,到目前为止,无论我尝试什么,都失败了。

谢谢你的帮助!

编辑:一些额外的澄清信息:

我有这个功能,它有效:

function provideData(year) {
return nations.map(function(d) {
  return {
    name: d.country,
    region: d.region,
income: d.income,
    population: d.population,
    lifeExpectancy: d.lifeExpectancy
  };
});
}

但是,正如您所期望的那样,它会返回完整的数组,从而输出超过一百年的数据。现在,如果 d.year == year 有办法返回 d.income 就好了。

4

3 回答 3

1

可以试试看Underscore.js Find一下答案:Filtering through a multidimensional array using underscore.js

于 2013-07-16T09:15:21.780 回答
1

如果您不想使用下划线,这应该可以通过 for 循环来实现。

var plotData = []

for(var i = 0; i < data.length; i++){
    if(data[i].year == targetYear){
        plotData.push(data[i]);
    }
}

我相信下划线也使用循环,因此效率损失不大。如果您知道一旦您的年份超过您的目标年份,您就可以通过打破 for 循环来对您的数据进行排序,您可以提高 for 循环的效率,如下所示:

function getData(data){

    var plotData = []

    for(var i = 0; i < data.length; i++){
        if(data[i].year == targetYear){
            plotData.push(data[i]);
        } else if(data[i].year > targetYear){
            return 0;
        }
    }

    return 0;
}

要使用插值,您可以在 for 循环中构建一个与预期数组匹配的数组,或者调用a.yearanda.value而不是a[0]and a[1]

于 2013-07-16T17:29:47.390 回答
0

您可以使用Alasql JavaScript SQL 库来做到这一点。

这是一个例子:

var data = [ {"region":"A","income":1178.0,"lifeExpectancy":788.0,"year":1800.0,"population":1292.0,"country":"Angola"},
     {"region":"B","income":847.0,"lifeExpectancy":1183.0,"year":1800,"population":803.0,"country":"Benin"},
     {"region":"A","income":798.0,"lifeExpectancy":765.0,"year":1801,"population":967.0,"country":"Angola"},
     {"region":"B","income":1293.0,"lifeExpectancy":1497.0,"year":1801,"population":792.0,"country":"Benin"}];

var res = alasql('SELECT MATRIX year, SUM(income) FROM ? GROUP BY year',[data]);

在 jsFiddle试试这个例子。

Alasql 使用带有一些 JavaScript 扩展的标准 SQL,因此您可以构造任何表达式

于 2014-12-21T15:29:07.613 回答