如何在数组 Javascript 中正确存储和格式化数据



我想使用图表.js库,并使图表中显示的数据取决于用户输入的内容。

现在我不太确定如何以正确的格式获取数据,以便我可以将 if 用于库。

目前,我在组合标签和值以使其与正确标签的正确索引匹配时遇到问题。 我有一个包含两个值的表(一个月(指定为 1 月、2 月、3 月、4 月等)和一个数值)

现在,我需要合并出现两次的月份,并添加与每个月关联的值。我真的不知道我应该为此使用 2d 数组还是 2 个数组。 例如

var labels = ["Jan 17", "Jan 17", "Feb 17", "Mar 17", "Mar 17"];
var values = [10,10,25,40,100];

成为

var newlabels = ["Jan 17", "Feb 17", "Mar 17"];
var newvalues = [20,25,140];

或作为 2D 阵列:

var graphdata = [["Jan 17", 10],["Jan 17",10],["Feb 17",25],["Mar 17",40],["Mar 17",100]];

成为

var newgraphData =[["Jan 17", 20],["Feb 17",25],["Mar 17",140]];

无论哪种方式都很好,但我不知道该使用哪种方式。我也不太知道如何使用 jQuery 选择器和 .map() 函数获取 2d 数组中的数据。

我正在考虑使用带有循环的 .map() 和 .reduce() 函数来遍历每个索引,但我似乎无法弄清楚如何做到这一点。

试试这个。您将在数组rLabelsrValues中获得格式化的数据。

var labels = ["Jan 17", "Jan 17", "Feb 17", "Mar 17", "Mar 17"]
, values = [10, 10, 25, 40, 100]
, rLabels = []
, rValues = [];
for (var i = 0; i < labels.length; i++) {
var label = labels[i];
var ind = rLabels.indexOf(label);
if (ind == -1) {
rLabels.push(label);
rValues.push(values[i]);
} else {
rValues[ind] += values[i];
}
}
const labels = ["Jan 17", "Jan 17", "Feb 17", "Mar 17", "Mar 17"];
const values = [10,10,25,40,100];
const result = labels.map((label, i) => ({label, value: values[i]}));
const grouped = []
result.forEach(o => {
if (!this[o.label]) {
this[o.label] = { label: o.label, value: 0 };
grouped.push(this[o.label]);
}
this[o.label].value += o.value;
}, {});
console.log(grouped) // [ { label: 'Jan 17', value: 20 }, { label: 'Feb 17', value: 25 }, { label: 'Mar 17', value: 140 } ]

这是另一种旨在将问题解构为更小部分的方法。一旦我们有了几个函数来高级转换数据,组装最终结果就变成了一项微不足道的任务。

我们可以从一种以类似拉链的方式合并您的两个列表的方法开始,使用zip

const None =
Symbol ()
const zip = ([ x = None, ...xs ], [ y = None, ...ys ]) =>
x === None || y === None
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
const labels =
[ "Jan 17", "Jan 17", "Feb 17", "Mar 17", "Mar 17" ]
const values =
[ 10, 10, 25, 40, 100 ]
console.log (zip (labels, values))
// [ [ 'Jan 17', 10 ]
// , [ 'Jan 17', 10 ]
// , [ 'Feb 17', 25 ]
// , [ 'Mar 17', 40 ]
// , [ 'Mar 17', 100 ] 
// ]

有了[ key, value ]对的列表,我们可以创建一个按key对值进行分组的 Map。由于对数搜索,地图快如闪电。JavaScript 为我们提供了 Map,所以在适用的情况下,最好使用它而不是普通的对象。至少,避免像一个答案建议的那样使用Array.prototype.indexOf因为它使用线性搜索并且不适合更大的数据集。

const group = (xs = []) =>
xs.reduce ((acc, [ key, value ]) =>
acc.has (key)
? acc.set (key, value + acc.get (key))
: acc.set (key, value),
new Map ())
console.log (group (zip (labels, values)))
// => Map { 'Jan 17' => 20, 'Feb 17' => 25, 'Mar 17' => 140 }

最后,我们可以使用 Array.from, Map.prototype.entries 从 Map 转换为您想要的输出类型

const main = (labels = [], values = []) =>
Array.from (group (zip (labels, values)) .entries ())

这是一个功能示例

const None =
Symbol ()
const zip = ([ x = None, ...xs ], [ y = None, ...ys ]) =>
x === None || y === None
? []
: [ [ x, y ] ] .concat (zip (xs, ys))

const group = (xs = []) =>
xs.reduce ((acc, [ key, value ]) =>
acc.has (key)
? acc.set (key, value + acc.get (key))
: acc.set (key, value),
new Map ())
const main = (labels = [], values = []) =>
Array.from (group (zip (labels, values)) .entries ())
const labels =
[ "Jan 17", "Jan 17", "Feb 17", "Mar 17", "Mar 17" ]

const values =
[ 10, 10, 25, 40, 100 ]
console.log (main (labels, values))
// [ [ 'Jan 17', 20 ]
// , [ 'Feb 17', 25 ]
// , [ 'Mar 17', 140 ]
// ]

最新更新