如何在数组内迭代两次

时间:2016-07-05 14:24:41

标签: javascript angularjs underscore.js

如何通过在其中迭代两次从数组中获取数据。例如,我有一个数据集:

var data = [
    {"Fruits ":"Apples","Fresh":"12","Rotten":"5","Total":"17"},
    {"Fruits ":"Oranges","Fresh":"34","Rotten":"6","Total":"40"},
    {"Fruits ":"Strawberries","Fresh":"67","Rotten":"8","Total":"75"},
    {"Fruits ":"Bananas","Fresh":"23","Rotten":"5","Total":"28"}
]

首先,我想在右侧进行迭代并获取所有键,直到第一个对象结束然后向下,这样我才能得到键的所有值,所以我得到了

预期输出

 [{ 'name': 'Fresh',
    'data': [12, 34, 67, 23]
    }, 
    {
    'name': 'Rotten',
    'data': [5, 6, 8, 5]
    },
    {
    'name': 'total',
    'data': [17, 40, 75, 28]
    }]

到目前为止,我已经尝试过这个:

    var categorie = []
    var seriesNames = []
    var series = []

    for(var i=0; i<data.length; i++){
      categorie.push(_.values(data[i])[0])
    }

    for(i=1; i<data.length; i++){
        seriesNames.push(_.keys(data[0])[i])
    }

但我很困惑如何获取数据数组并将其与seriesName连接。实时副本:plunker

修改 由于我处理的是动态数据,因此键,值和数据长度都是可变的。

10 个答案:

答案 0 :(得分:4)

您可以使用组数组并将其用于结果数组中的正确分组。

var data = [{ "Fruits ": "Apples", "Fresh": "12", "Rotten": "5", "Total": "17" }, { "Fruits ": "Oranges", "Fresh": "34", "Rotten": "6", "Total": "40" }, { "Fruits ": "Strawberries", "Fresh": "67", "Rotten": "8", "Total": "75" }, { "Fruits ": "Bananas", "Fresh": "23", "Rotten": "5", "Total": "28" }],
    groups = ["Fresh", "Rotten", "Total"],
    result = [];

data.forEach(function (a) {
    groups.forEach(function (b, i) {
        result[i] = result[i] || { name: b, data: [] };
        result[i].data.push(+a[b]);
    });
});

console.log(result);

对动态属性略有改动的建议。它只需要有限数字的属性。

var data = [{ "Fruits ": "Apples", "Fresh": "12", "Rotten": "5", "Total": "17" }, { "Fruits ": "Oranges", "Fresh": "34", "Rotten": "6", "Total": "40" }, { "Fruits ": "Strawberries", "Fresh": "67", "Rotten": "8", "Total": "75" }, { "Fruits ": "Bananas", "Fresh": "23", "Rotten": "5", "Total": "28" }],
    result = [];

data.forEach(function (a) {
    Object.keys(a).forEach(function (k) {
        if (isFinite(a[k])) {
            if (!this[k]) {
                this[k] = { name: k, data: [] };
                result.push(this[k]);
            }
            this[k].data.push(a[k]);
        }
    }, this);
}, Object.create(null));

console.log(result);

答案 1 :(得分:2)

使用array.prototype.map

&#13;
&#13;
var arr = [
{"Fruits ":"Apples","Fresh":"12","Rotten":"5","Total":"17"},
{"Fruits ":"Oranges","Fresh":"34","Rotten":"6","Total":"40"},
{"Fruits ":"Strawberries","Fresh":"67","Rotten":"8","Total":"75"},
{"Fruits ":"Bananas","Fresh":"23","Rotten":"5","Total":"28"}
];

var newArr = ["Fresh", "Rotten", "Total"].map(function(item) {
  return {
    name: item,
    data: arr.map(function(innerItem) {
      return parseInt(innerItem[item],10);
    })
  }
});

console.log(newArr);
&#13;
&#13;
&#13;

答案 2 :(得分:2)

您可以尝试这样的事情:

您可以拥有需要排除的密钥列表,并根据此列表处理密钥。

var data = [{"Fruits ":"Apples","Fresh":"12","Rotten":"5","Total":"17"},
{"Fruits ":"Oranges","Fresh":"34","Rotten":"6","Total":"40"},
{"Fruits ":"Strawberries","Fresh":"67","Rotten":"8","Total":"75"},
{"Fruits ":"Bananas","Fresh":"23","Rotten":"5","Total":"28"}
]
var keys_to_exclude = ["Fruits"];
var _tmp = {};

data.forEach(function(o) {
  for (var k in o) {
    if (keys_to_exclude.indexOf(k.trim()) < 0) {
      _tmp[k] = _tmp[k] || [];
      _tmp[k].push(o[k]);
    }
  }
});

var result = Object.keys(_tmp).map(function(k) {
  return {
    name: k,
    data: _tmp[k]
  }
});

document.getElementById("r").innerHTML = JSON.stringify(result, 0, 4);
<pre id="r"></pre>

答案 3 :(得分:1)

由于您使用的是underscore,因此它实际上非常简单map

首先,找到对象的键。

稍后,使用map,您可以获取对象的必需属性。

var keys = _.keys(data[0]).reverse()
keys = _.without(keys, keys[0]) 


var c = _.map(keys, function(k) {
  return {
    name: k,
    data: _.map(data, k)
  };
});

还有一个吸虫:https://plnkr.co/edit/KtJPMu?p=preview

答案 4 :(得分:0)

以下是一种方法:

<?php include_once "filePath"; ?>

答案 5 :(得分:0)

我建议你直接使用输出对象,然后将它们添加到数组中:

var data = [{"Fruits ": "Apples","Fresh": "12","Rotten": "5","Total": "17"}, {"Fruits ": "Oranges","Fresh": "34","Rotten": "6","Total": "40"}, {"Fruits ": "Strawberries","Fresh": "67","Rotten": "8","Total": "75"}, {"Fruits ": "Bananas","Fresh": "23","Rotten": "5","Total": "28"}];

var fresh = {name: 'Fresh', data: []};
var rotten = {name: 'Rotten', data: []};
var total = {name: 'Total', data: []};

data.forEach(function(fruit) {
  fresh.data.push(+fruit.Fresh);
  rotten.data.push(+fruit.Rotten);
  total.data.push(+fruit.Total)
});

var output = [fresh, rotten, total];
console.log(output);

答案 6 :(得分:0)

试试这个:

var result = [
  {'name':'Fresh', 'data':[]},
  {'name':'Rotten', 'data':[]},
  {'name':'Total', 'data':[]}
];

for (d of data) {
  result[0].data.push(d['Fresh']);
  result[1].data.push(d['Rotten']);
  result[2].data.push(d['Total']);
}

输出如下:

[{"name":"Fresh","data":["12","34","67","23"]},
{"name":"Rotten","data":["5","6","8","5"]},
{"name":"Total","data":["17","40","75","28"]}]

答案 7 :(得分:0)

我会推荐@ nina-scholz的答案。但是,如果有人想知道它在简单的JS中是如何完成的,请参考下面的代码:

var data = [{"Fruits ":"Apples","Fresh":"12","Rotten":"5","Total":"17"},
{"Fruits ":"Oranges","Fresh":"34","Rotten":"6","Total":"40"},
{"Fruits ":"Strawberries","Fresh":"67","Rotten":"8","Total":"75"},
{"Fruits ":"Bananas","Fresh":"23","Rotten":"5","Total":"28"}]

//list of items that needs to be in the final list
var categorie = ["Fresh", "Rotten", "Total"];
var seriesNames = {};
var series = [];

// iterate through the initial array
for(var i=0; i<data.length; i++){
  // iterate through the category
  for(var j=0; j<categorie.length; j++) {
    if(data[i].hasOwnProperty(categorie[j])) {
        // seriesNames will hold the category name and corresponding value will be an array of values(total, rotten, fresh) from all objects
        if(seriesNames[categorie[j]]) { // array already exists
            var arr = seriesNames[categorie[j]];
            arr.push(data[i][categorie[j]]);
        } else { // create a new array
            seriesNames[categorie[j]] = new Array();
        }
    }
  }
}

// create the required output object
for(var attr in seriesNames) {
    var obj = {};
    obj['name'] = attr;
    obj['data'] = seriesNames[attr];
    series.push(obj);
}

// expected output is in series.
console.debug(series);

答案 8 :(得分:0)

var i, j, ref, output = { Fresh: [], Rotten: [], Total: [] }; //ignore anything that isn't here.
for (i of data) {
  for (j in i) {
    if (typeof (ref = output[j]) !== 'undefined')
      ref.push(i[j]);
  }
}

output看起来像这样(JSON)

{
  "Fresh":["12","34","67","23"],
  "Rotten":["5","6","8","5"],
  "Total":["17","40","75","28"]
}

这不是您想要的格式,因此我们可以再次使用它:

var output2 = [];
for (k in output) {
  output2.push({ name: k, data: output[k] });
}

output2现在应该看起来像你想要的(JSON)

[{
  "name":"Fresh",
  "data":["12","34","67","23"]
},{
  "name":"Rotten",
  "data":["5","6","8","5"]
},{
  "name":"Total",
  "data":["17","40","75","28"]
}]

为了完善它,我们可以将它们全部放在一个函数中

function nameMeSomething(data) {
  var i, j, k, l, m = [], n = { Fresh: [], Rotten: [], Total: [] }; //ignore anything that isn't here.
  for (i of data) for (j in i) if (typeof (l = n[j]) !== 'undefined') l.push(i[j]);
  for (k in n) m.push({ name: k, data: m[k] });
  return m
}

答案 9 :(得分:0)

我的解决方案获取所有具有数值的键(这不仅仅是PO的条款)并完全链接为一行答案。

&#13;
&#13;
var data = [{ "Fruits ": "Apples", "Fresh": "12", "Rotten": "5", "Total": "17" }, { "Fruits ": "Oranges", "Fresh": "34", "Rotten": "6", "Total": "40" }, { "Fruits ": "Strawberries", "Fresh": "67", "Rotten": "8", "Total": "75" }, { "Fruits ": "Bananas", "Fresh": "23", "Rotten": "5", "Total": "28" }];

var result = Object.keys(data[0])
  .filter(k => !isNaN(data[0][k]))
  .map(k => ({
    name: k,
    data: data.map(d => d[k])
  }));

console.log(result);
&#13;
&#13;
&#13;