我正在尝试从一个数组中获取数据,按对象属性对数据进行分组,然后将其发送到新数组。目前的数据格式如下:
const data = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": [
"a","b","c"
]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": [
"d","e","f",
]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [
1,2,3
]
}
];
我使用了Lodash groupby方法,该方法以一种接近我期望的格式对项目进行分组,但不完全是我想要的最终结果。 lodash结果是:
[
[
{ "tableName": 'table1',
"dataId": '1',
"header": 'firstHeader',
"rows": ["a","b","c"]
},
{ "tableName": 'table1',
"dataId": '1',
"header": 'secondHeader',
"rows": ["d","e","f"]
}
],
[
{ "tableName": 'table2',
"dataId": '2',
"header": 'aNewFirstHeader',
"rows": [1,2,3] },
]
]
最终,我要找的是最终结果:
[
{
"tableName": "table1",
"column": ["firstHeader", "secondHeader"],
"rows": [["a","b","c"], ["d","e","f"]]
},
{
"tableName": "table2",
"column": ["aNewFirstHeader"],
"rows": [[1,2,3]]
}
]
有没有不同的方法来使用groupBy方法,或者可能只使用javascript方法来获得我想要的最终结果?
答案 0 :(得分:1)
通过使用reduce
和findIndex
,我们可以在O(n)时间内重建适合您格式的新数组。
data.reduce((arr, record) => {
const index = arr.findIndex((inside) => (inside.tableName === record.tableName));
if (index === -1) {
arr.push({
tableName: record.tableName,
column: [record.column],
rows: [record.rows]
})
} else {
arr[index].column.push(record.column);
arr[index].rows.push(record.rows);
}
return arr;
}, []);
const data = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": [
"a", "b", "c"
]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": [
"d", "e", "f",
]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [
1, 2, 3
]
}
];
const newData = data.reduce((arr, record) => {
const index = arr.findIndex((inside) => (inside.tableName === record.tableName));
if (index === -1) {
arr.push({
tableName: record.tableName,
column: [record.column],
rows: [record.rows]
})
} else {
arr[index].column.push(record.column);
arr[index].rows.push(record.rows);
}
return arr;
}, []);
console.log(newData);

答案 1 :(得分:0)
试试这个,仅使用普通香草js:
var merge = function( data){
var outputArray = [], enteredNames = [];
for(var i=0; i<data.length; i++){
var datum = data[i];
var ownElement;
if(enteredNames.indexOf(datum.tableName)>-1)
ownElement = outputArray[enteredNames.indexOf(datum.tableName)];
else
{
ownElement = {
"tableName": datum.tableName,
"column": [],
"rows": []
}
enteredNames.push( datum.tableName );
outputArray.push( ownElement );
}
ownElement.column.push( datum.column );
ownElement.rows.push( datum.rows );
}
return outputArray;
}
答案 2 :(得分:0)
使用内置的JavaScript数组原型方法map
和reduce
来简化您的问题:
const data = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": [
"a", "b", "c"
]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": [
"d", "e", "f",
]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [
1, 2, 3
]
}
];
const EXPECTED = [
{
"tableName": "table1",
"column": ["firstHeader", "secondHeader"],
"rows": [["a", "b", "c"], ["d", "e", "f"]]
},
{
"tableName": "table2",
"column": ["aNewFirstHeader"],
"rows": [[1, 2, 3]]
}
];
var result = data
.reduce((hash, dataItem) => {
// first group by tableName
if (hash[dataItem.tableName]) {
hash[dataItem.tableName].column.push(dataItem.column);
hash[dataItem.tableName].rows.push(dataItem.rows);
} else {
hash[dataItem.tableName] = {
column: [dataItem.column],
rows: [dataItem.rows]
};
}
return hash;
}, {});
// run a map to change to the exact array style you want
result = Object.keys(result).map((tableName) => {
return {
tableName: tableName,
column: result[tableName].column,
rows: result[tableName].rows
};
});
// if in a node environment, you can assert (for unit testing only)
require('assert').deepStrictEqual(result, EXPECTED);
答案 3 :(得分:0)
const data = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": [
"a","b","c"
]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": [
"d","e","f",
]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [
1,2,3
]
}
];
var result = _.chain(data)
.groupBy("tableName")
.pairs()
.map(function (currentItem) {
// used to create desired properties
var rows = [];
var columns = [];
// loop to fill values
for(var i=0,length=currentItem[1].length;i<length;i++){
columns.push(currentItem[1][i].column)
rows = rows.concat(currentItem[1][i].rows);
}
return {
'tableName': currentItem[0],
'column': columns,
'rows': rows
};
})
.value();
console.log(result);
答案 4 :(得分:0)
.findIndex()
是一件事。这是更新的解决方案:
使用.map()
,.reduce()
&amp; .findIndex()
:
const newArr = data.map(value => ({
tableName: value.tableName,
column: [value.column],
rows: [value.rows],
}))
.reduce((acc, cur) => {
const tableNameIndex = acc.findIndex(el => el.tableName === cur.tableName);
if (tableNameIndex !== -1) {
acc[tableNameIndex].column.push(cur.column[0]);
acc[tableNameIndex].rows.push(cur.rows[0]);
return acc;
} else {
acc.push(cur);
return acc;
}
}, [])
console.log(newArr);
答案 5 :(得分:0)
使用+---------+------------+-----------------------------+-----------------------------+
| Line Operation | StartDate | EndDate |
+---------+------------+-----------------------------+-----------------------------+
| ACOE | OP10 | 2017-01-27 10:00:00.000 | 2017-01-27 11:10:00.000 |
| ACOE | OP20 | 2017-01-27 11:10:00.000 | 2017-01-27 11:25:00.000 |
| ACOE | OP30 | 2017-01-27 12:10:00.000 | 2017-01-27 12:25:00.000 |
+---------+------------+-----------------------------+-----------------------------+
使用_.groupBy()
映射每个组以将组中的所有对象组合到新对象后,将除_.mergeWith()
之外的所有内容推送到数组中。然后使用tableName
删除_.omit()
:
dataId
&#13;
const data = [{"dataId":"1","tableName":"table1","column":"firstHeader","rows":["a","b","c"]},{"dataId":"2","tableName":"table1","column":"secondHeader","rows":["d","e","f"]},{"dataId":"3","tableName":"table2","column":"aNewFirstHeader","rows":[1,2,3]}];
const result = _(data)
.groupBy('tableName')
.map((group) => // map each group
// remove the dataId property
_.omit(
// merge all group objects
_.mergeWith({}, ...group, (objValue = [], srcValue, key) => {
// if the key is not tableName push it into the array
if (key !== 'tableName') {
objValue.push(srcValue);
return objValue;
}
}),
'dataId'))
.value();
console.log(result);
&#13;
答案 6 :(得分:0)
普通Javascript:
function groupBy(data, fieldName) {
var groups = {}
for (var i=0; i<data.length; i++) {
var elem = data[i];
if (fieldName in elem) {
var fieldVal = elem[fieldName];
if (!(fieldVal in groups)) {
groups[fieldVal] = [];
}
groups[fieldVal].push(elem)
}
}
var result = [];
for (list in groups) {
var arr = groups[list];
var combine = {}
combine[fieldName] = arr[0][fieldName];
for (var i=0; i<arr.length; i++) {
var elem = arr[i];
for (prop in elem) {
if (prop == fieldName) {
continue;
}
if (!(prop in combine)) {
combine[prop] = [];
}
combine[prop].push(elem[prop]);
}
}
result.push(combine);
}
return result;
}
对于您的情况,只需调用:
groupBy(data, "tableName")
答案 7 :(得分:0)
在普通的Javascript中,您可以使用Map
var data = [{ dataId: "1", tableName: "table1", column: "firstHeader", rows: ["a", "b", "c"] }, { dataId: "2", tableName: "table1", column: "secondHeader", rows: ["d", "e", "f", ] }, { dataId: "3", tableName: "table2", column: "aNewFirstHeader", rows: [1, 2, 3] }],
result = data.reduce((map => (r, a) => {
var item = map.get(a.tableName);
if (!item) {
item = { tableName: a.tableName, column: [], rows: [] }
map.set(a.tableName, item);
r.push(item);
}
item.column.push(a.column);
item.rows.push(a.rows);
return r;
})(new Map), []);
console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;