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

时间:2018-01-27 18:26:07

标签: javascript jquery arrays

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

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

目前,我在组合标签和值时遇到问题,因此它与正确标签的正确索引相匹配。 我有一个两个值的表(一个月(指定为Jan,Feb,Mar,Apr.etc。)和一个数值)

现在我需要将出现两次的月份组合起来并添加与每个月相关联的值。我真的不知道我是否应该使用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()函数在二维数组中获取数据。

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

3 个答案:

答案 0 :(得分:1)

试试这个。您将获得数组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];
    }
}

答案 1 :(得分:1)

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 } ]

答案 2 :(得分:1)

这是另一种旨在将问题解构为较小部分的方法。一旦我们有几个函数以高级方式转换数据,汇总最终结果将成为一项微不足道的任务。

我们可以首先使用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 ]对列表,我们可以创建一个Map,按key对值进行分组。由于logarithmic search,地图闪电般快速。 JavaScript为我们提供了Map,因此在适用时,最好使用它而不是普通的Object。至少,请避免使用Array.prototype.indexOf,因为它使用linear search并且不适合更大的数据集。

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.fromMap.prototype.entries

将地图转换为您想要的输出类型
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 ]
// ]