如何在数组中迭代两次
How to iterate two times inside an array
如何通过在数组中迭代两次来从数组中获取数据。例如我有一个数据集:
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
编辑
键、值和数据长度是可变的,因为我正在处理动态数据。
这是一种方法:
var output = data.reduce(function(acc, cur) {
for(var k in cur) {
if (!cur.hasOwnProperty(k) || k === 'Fruits ') {
continue;
}
var container = acc.filter(function(item) {
return item.name === k;
})[0];
if (!container) {
container = {
name: k,
data: []
};
acc.push(container);
}
container.data.push(cur[k])
}
return acc;
},[]);
您可以使用组数组并将其用于结果数组中的正确分组。
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);
我建议您直接使用输出对象,稍后将它们添加到数组中:
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);
由于您使用的是 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)
};
});
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);
您可以尝试这样的操作:
您可以有一个需要排除的键列表,并根据这个列表处理键。
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>
试试这个:
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"]}]
我会在上面推荐@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);
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
}
我的解决方案获取所有具有数值(超过 PO 的条款)的键并完全链接为一行答案。
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);
如何通过在数组中迭代两次来从数组中获取数据。例如我有一个数据集:
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
编辑 键、值和数据长度是可变的,因为我正在处理动态数据。
这是一种方法:
var output = data.reduce(function(acc, cur) {
for(var k in cur) {
if (!cur.hasOwnProperty(k) || k === 'Fruits ') {
continue;
}
var container = acc.filter(function(item) {
return item.name === k;
})[0];
if (!container) {
container = {
name: k,
data: []
};
acc.push(container);
}
container.data.push(cur[k])
}
return acc;
},[]);
您可以使用组数组并将其用于结果数组中的正确分组。
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);
我建议您直接使用输出对象,稍后将它们添加到数组中:
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);
由于您使用的是 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)
};
});
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);
您可以尝试这样的操作:
您可以有一个需要排除的键列表,并根据这个列表处理键。
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>
试试这个:
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"]}]
我会在上面推荐@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);
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
}
我的解决方案获取所有具有数值(超过 PO 的条款)的键并完全链接为一行答案。
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);