1

州ごとの年間GDP、収入、人口などの値を含むネストされたオブジェクトの配列があります。

// The "records" array looks like this:
[
    {
        name : "...",
        income : [
            [1995, 1234], // [year, value]
            [1996. 1235],
            [...]
        ],
        GDP : [
            [1995, 1234],
            [1996. 1235],
            [...]
        ],
        population : [
            [1995, 1234],
            [1996. 1235],
            [...]
        ]
    }, {
        name : "...",
        income : [
            [...]
        ],
        GDP : [
            [...]
        ],
        population : [
            [...]
        ]
    }, {
        ...
    }
]

ここで、すべての州と年にわたる各次元の最小値と最大値(範囲)を見つけたいと思います。

populationExtents = [659651, 82536680];
gdpExtents        = [14250, 2498800];
incomeExtents     = [..., ...];

配列全体を複数回トラバースすることなく、これを行うにはどうすればよいですか?現在、私は各次元に対してこれを行っています:

var income = records.map(function(d, i) {
    return d.income;
});

var min = d3.min(income, function(d, i) {
    return d3.min(d, function(e) {
            return e[1]; // returns values of each year
        });
});

var max = d3.max(income, function(d, i) {
    return d3.max(d, function(e) {
            return e[1];
        });
});

しかし、これは非常に複雑すぎると思います。次元と状態ごとにすべての「ローカル」最小値を計算してから、(次元ごとに1つのパスではなく)パスですべての状態のグローバル最小値を計算できるはずだからです。

いくつかのレベルのd3.mapとネストされたd3.minを試しましたが、この構造に頭を包むことができません。

4

2 に答える 2

3
function getMaxMin( prop ) {
    var concat = [].concat,
        arr = concat.apply([], records.map(function(value) {
            return concat.apply([], value[prop]);
        }));

    return [ Math.min.apply(Math.min, arr), Math.max.apply(Math.max, arr) ];
}

または少しきれい:

function getMaxMin( prop ) {
    var arr = [];

    records.map(function(value) {
        arr = arr.concat.apply(arr, value[prop][1]);
    });

    return [ Math.min.apply(Math.min, arr), Math.max.apply(Math.max, arr) ];
}

編集:年を除外[year, value]し、ほとんどすべてを同じループの下に置くには:

function getMaxMin() {
    var arrs = [];

    records.map(function(value) {
        arrs[0] = arrs[0].concat(value.income);
        arrs[1] = arrs[1].concat(value.GDP);
        arrs[2] = arrs[2].concat(value.population);
    });

    arrs[0] = arrs[0].filter(c);
    arrs[1] = arrs[1].filter(c);
    arrs[2] = arrs[2].filter(c);

    function c(value, key) {
        return key % 2;
    }

    return [
        [ Math.min.apply(Math.min, arrs[0]), Math.max.apply(Math.max, arrs[0]) ],
        [ Math.min.apply(Math.min, arrs[1]), Math.max.apply(Math.max, arrs[1]) ],
        [ Math.min.apply(Math.min, arrs[2]), Math.max.apply(Math.max, arrs[2]) ]
    ];
}

var maxMin = getMaxMin();

maxMin === [
    [income-min, income-max],
    [GDP-min, GDP-max],
    [population-min, population-max]
]

デモ: http: //jsbin.com/ecineg/1/embed?javascript 、console

于 2013-01-08T14:23:50.813 に答える
0

JavaScriptMath.maxMath.min関数をで使用applyして、配列の最大値と最小値を取得できます。私が使用している配列を取得し、reduce各レコードのプロパティを連結するには

var allValues = function (property) {
  return records.reduce(function (memo, record) {
    return memo.concat(record[property])
  }, [])
}

var allIncome = allValues('income')

Math.max.apply(null, allIncome)
Math.min.apply(null, allIncome)
于 2013-01-08T14:19:25.447 に答える