我一直在解决这个问题,为chart.js data source生成2个数组。
let data = [
{ date: '7/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 100 },
{ date: '7/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 200 },
{ date: '7/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 10 },
{ date: '7/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 110 },
{ date: '8/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 120 },
{ date: '8/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 30 },
{ date: '8/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 60 },
{ date: '8/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 70 }
];
给定此输入数据并通过可变数量的列分组,例如在我的示例名称和租户中,但可以只是1,比如日期,生成标签键,然后是图表数据集数据的总和。
目标标签输出:
let targetLabels = [
['7/6/2016', 'BiggeCo'],
['7/6/2016', 'SmallCo'],
['8/6/2016', 'BiggeCo'],
['8/6/2016', 'SmallCo']
];
目标数据集输出:
let targetDataSets = [
{
label: 'Count',
data: [300, 120, 150, 130]
}
];
到目前为止,我已经得到了以下内容,但它似乎很笨拙,而且我不确定如何获得计数列的总和并轻松地允许可变数量的列。
let temp = _.transform(data, function(result, value, key) {
if (!_.some(result, function (r) { return r[0] == value['date'] && r[1] == value['tenant']; })) {
result.push([ value['date'], value['tenant'] ]);
}
}, []);
在SQL中我只写
SELECT name, tenant, sum(count) FROM table GROUP BY name, tenant
有人可以提供任何指导吗?
这看起来很接近我想要做的但我想在多个属性
上做答案 0 :(得分:3)
这是一个lodash
解决方案:
let fields = ['date', 'tenant']; // fields for ordering and picking
let groupFn = v => [v.date, v.tenant]; // grouping date and tenant
let sumBy = v => _.sumBy(v, 'count'); // get sum by `count`
let countBy = group => _(group[0])
.pick(fields) // pick `date` and `tenant` from the first item
.assign({ count: _.sumBy(group, 'count') }) // assign the total `count`
.value();
let source = _(data)
.orderBy(fields) // order data by `date` and `tenant`
.groupBy(groupFn) // group items by `date` and `tenant`
.map(countBy); // get count of each group
// get `date` and `tenant` values only
let targetLabels = source.map(groupFn).value();
let targetDataSets = [
{
label: 'count',
// get `count` values only
data: source.map('count').value()
}
];
// `date`, `tenant` and total `count` values only
let unified = source.value();
let data = [{
date: '7/6/2016',
tenant: 'BiggeCo',
template: 'Meeting Room',
count: 100
}, {
date: '8/6/2016',
tenant: 'SmallCo',
template: 'All Hands MR',
count: 70
}, {
date: '7/6/2016',
tenant: 'BiggeCo',
template: 'All Hands MR',
count: 200
}, {
date: '7/6/2016',
tenant: 'SmallCo',
template: 'Meeting Room',
count: 10
}, {
date: '7/6/2016',
tenant: 'SmallCo',
template: 'All Hands MR',
count: 110
}, {
date: '8/6/2016',
tenant: 'BiggeCo',
template: 'Meeting Room',
count: 120
}, {
date: '8/6/2016',
tenant: 'BiggeCo',
template: 'All Hands MR',
count: 30
}, {
date: '8/6/2016',
tenant: 'SmallCo',
template: 'Meeting Room',
count: 60
}];
let fields = ['date', 'tenant']; // fields for ordering and picking
let groupFn = v => [v.date, v.tenant]; // grouping date and tenant
let sumBy = v => _.sumBy(v, 'count'); // get sum by `count`
let countBy = group => _(group[0])
.pick(fields) // pick `date` and `tenant` from the first item
.assign({ count: _.sumBy(group, 'count') }) // assign the total `count`
.value();
let source = _(data)
.orderBy(fields) // order data by `date` and `tenant`
.groupBy(groupFn) // group items by `date` and `tenant`
.map(countBy); // get count of each group
// get `date` and `tenant` values only
let targetLabels = source.map(groupFn).value();
let targetDataSets = [
{
label: 'count',
// get `count` values only
data: source.map('count').value()
}
];
// `date`, `tenant` and total `count` values only
let unified = source.value();
document.body.innerHTML =
'<strong>Data Sets</strong>' +
'<pre>' + JSON.stringify(targetDataSets, 0, 4) + '</pre><hr>' +
'<strong>Labels</strong>' +
'<pre>' + JSON.stringify(targetLabels, 0, 4) + '</pre><hr>' +
'<strong>Unified Value</strong>' +
'<pre>' + JSON.stringify(unified, 0, 4) + '</pre>';
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
答案 1 :(得分:1)
假设data
始终排序,您可以尝试这样的事情:
count
并继续,否则推入临时数组。
var data=[{date:"7/6/2016",tenant:"BiggeCo",template:"Meeting Room",count:100},{date:"7/6/2016",tenant:"BiggeCo",template:"All Hands MR",count:200},{date:"7/6/2016",tenant:"SmallCo",template:"Meeting Room",count:10},{date:"7/6/2016",tenant:"SmallCo",template:"All Hands MR",count:110},{date:"8/6/2016",tenant:"BiggeCo",template:"Meeting Room",count:120},{date:"8/6/2016",tenant:"BiggeCo",template:"All Hands MR",count:30},{date:"8/6/2016",tenant:"SmallCo",template:"Meeting Room",count:60},{date:"8/6/2016",tenant:"SmallCo",template:"All Hands MR",count:70}];
var result = [];
data.reduce(function(c, n, i) {
if (c) {
if (c.date === n.date && c.tenant === n.tenant) {
n.count += c.count;
if (i === data.length - 1)
result.push(n);
} else {
result.push(c);
}
}
return n;
}, null)
var targetLabels = [];
var targetDataset = [{
label: "count",
data: []
}];
result.forEach(function(o) {
targetLabels.push([o.date, o.tenant]);
targetDataset[0].data.push(o.count);
})
console.log(targetLabels)
console.log(targetDataset)
&#13;
对于未分类的情况,您可以尝试手动排序,
data.sort(function(a, b) {
if (a.date === b.date) {
return a.tenant > b.tenant ? 1 : a.tenant < b.tenant ? -1 : 0;
} else {
return a.date > b.date ? 1 : a.date < b.date ? -1 : 0;
}
})
答案 2 :(得分:0)
只要我理解正确,你想按日期分组(我看不到属性名称)和tennant。
var data = [{ date: '7/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 100 }, { date: '7/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 200 }, { date: '7/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 10 }, { date: '7/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 110 }, { date: '8/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 120 }, { date: '8/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 30 }, { date: '8/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 60 }, { date: '8/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 70 }],
result = []
data.forEach(function (a) {
var key = a.date + '|' + a.tenant;
if (!this[key]) {
this[key] = { date: a.date, tenant: a.tenant, count: 0 };
result.push(this[key]);
}
this[key].count += a.count;
}, Object.create(null));
console.log(result);
答案 3 :(得分:0)
.reduce
应该这样做。您可能必须确保数据已排序。
let data = [
{ date: '7/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 100 },
{ date: '7/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 200 },
{ date: '7/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 10 },
{ date: '7/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 110 },
{ date: '8/6/2016', tenant: 'BiggeCo', template: 'Meeting Room', count: 120 },
{ date: '8/6/2016', tenant: 'BiggeCo', template: 'All Hands MR', count: 30 },
{ date: '8/6/2016', tenant: 'SmallCo', template: 'Meeting Room', count: 60 },
{ date: '8/6/2016', tenant: 'SmallCo', template: 'All Hands MR', count: 70 }
];
let targetDataSets = [{
label: 'Count',
data: []
}];
let targetLabels = [];
data.reduce( (p, c) => {
let cnt = 0;
if(p.hasOwnProperty('date')) {
if(p.date === c.date && p.tenant === c.tenant) {
cnt = p.count + c.count;
targetLabels.push([c.date, c.tenant]);
targetDataSets[0]['data'].push(cnt);
}
}
return c;
},{})
console.log(targetLabels)
console.log(targetDataSets)
&#13;
答案 4 :(得分:0)
受到答案的启发,我坐下来正确地学习了lodash groupBy
,map
和reduce
。
我的目标以及为什么我将问题视为搜索我无法找到执行以下操作的解决方案:
解决方案:
function group (data, groupKeys, sumKey) {
return _.chain(data)
.groupBy(function (d) {
let grouping = '';
for (let groupKey of groupKeys) {
grouping += d[groupKey] + '|||';
}
return grouping;
})
.map(function (groupedRow) {
let newRow = {};
// Extract the grouped properties to the new row
for (let groupKey of groupKeys) {
newRow[groupKey] = groupedRow[0][groupKey];
}
// Could use native reduce, browser support?
// Aggregate the sumKey property to the new row
newRow[sumKey] = _.reduce(groupedRow, function (sum, r) {
return sum + r[sumKey];
}, 0);
return newRow;
})
.value();
}
let groupKeys = ['date', 'tenant'];
let sumKey = 'count';
let temp4 = group(data, groupKeys, sumKey);
console.log('output', temp4);
console.log('labels',
_.map(temp4, function (row) {
let newRow = {};
for (let groupKey of groupKeys) {
newRow[groupKey] = row[groupKey];
}
return newRow;
})
);
console.log('dataSets',
_.map(temp4, sumKey)
);
输出:
phil $ node index.js
output
[ { date: '7/6/2016', tenant: 'BiggeCo', count: 300 },
{ date: '7/6/2016', tenant: 'SmallCo', count: 120 },
{ date: '8/6/2016', tenant: 'BiggeCo', count: 150 },
{ date: '8/6/2016', tenant: 'SmallCo', count: 130 } ]
labels
[ { date: '7/6/2016', tenant: 'BiggeCo' },
{ date: '7/6/2016', tenant: 'SmallCo' },
{ date: '8/6/2016', tenant: 'BiggeCo' },
{ date: '8/6/2016', tenant: 'SmallCo' } ]
dataSets [ 300, 120, 150, 130 ]