I have a dataset like this:
我有这样的数据集:
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: v1},
{time: "t1", locA: "a1", locB: "b2", value: v2},
{time: "t1", locA: "a2", locB: "b1", value: v3},
{time: "t1", locA: "a2", locB: "b2", value: v4},
{time: "t2", locA: "a1", locB: "b1", value: v5},
{time: "t2", locA: "a1", locB: "b2", value: v6},
{time: "t2", locA: "a2", locB: "b1", value: v7},
{time: "t2", locA: "a2", locB: "b2", value: v8},
....
];
I want a result like this:
我想要一个这样的结果:
var a1b1 = [
{loc: "a1b1", time: "t1", value: "v1"},
{loc: "a1b1", time: "t2", value: "v5"},
....
];
var a1b2 = [
{loc: "a1b2", time: "t1", value: "v2"},
{loc: "a1b2", time: "t2", value: "v6"},
....
];
var a2b1 = [
{loc: "a2b1", time: "t1", value: "v3"},
{loc: "a2b1", time: "t2", value: "v7"},
....
];
var a2b2 = [
{loc: "a2b2", time: "t1", value: "v4"},
{loc: "a2b2", time: "t2", value: "v8"},
....
];
It's important that the t values are in the correct order while it represents time. I cannot use libraries, just vintage JavaScript. I found some older SO posts with splitting an array of objects but they describe just simple splitting or using libraries.
重要的是t值表示正确的顺序,而它代表时间。我不能使用库,只有老式JavaScript。我发现了一些较旧的SO帖子,它们拆分了一个对象数组,但它们描述的只是简单的拆分或使用库。
Is it possible with forEach like
是否可以与forEach一样
dataset.forEach(function()...
Any help is appreciated..
任何帮助表示赞赏..
5 个解决方案
#1
2
Another short Array.prototype.reduce()
approach:
另一个简短的Array.prototype.reduce()方法:
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: "v1"}, {time: "t1", locA: "a1", locB: "b2", value: "v2"}, {time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"}, {time: "t2", locA: "a1", locB: "b1", value: "v5"}, {time: "t2", locA: "a1", locB: "b2", value: "v6"}, {time: "t2", locA: "a2", locB: "b1", value: "v7"}, {time: "t2", locA: "a2", locB: "b2", value: "v8"}
];
var result = dataset.reduce(function(r, o){
var k = o.locA + o.locB; // unique `loc` key
if (r[k] || (r[k]=[])) r[k].push({loc:k, time: o.time, value: o.value});
return r;
}, {});
console.log(result);
#2
1
Something like this?
像这样的东西?
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: 0},
{time: "t1", locA: "a1", locB: "b2", value: 1},
{time: "t1", locA: "a2", locB: "b1", value: 2},
{time: "t1", locA: "a2", locB: "b2", value: 3},
{time: "t2", locA: "a1", locB: "b1", value: 4},
{time: "t2", locA: "a1", locB: "b2", value: 5},
{time: "t2", locA: "a2", locB: "b1", value: 6},
{time: "t2", locA: "a2", locB: "b2", value: 7}
];
var result = {};
dataset
.sort((a, b) => {
return Number(a.time.replace(/\D/g, '')) > Number(b.time.replace(/\D/g, ''));
})
.forEach(d => {
var key = d.locA + d.locB;
if (!result[key]) {
result[key] = [];
}
result[key].push({
loc: key,
time: d.time,
value: d.value
});
});
console.log(result);
If you really want to create vars like var a1b1
instead of an object as result, replace result[key]
with window[key]
inside the loop.
如果你真的想要创建变量如var a1b1而不是对象作为结果,请在循环内用window [key]替换result [key]。
#3
1
You can use reduce
to group the objects:
您可以使用reduce对对象进行分组:
function group(arr) {
return arr.reduce(function(res, obj) { // for each object obj in the array arr
var key = obj.locA + obj.locB; // let key be the concatination of locA and locB
var newObj = {loc: key, time: obj.time, value: obj.value}; // create a new object based on the object obj
if(res[key]) // if res has a sub-array for the current key then...
res[key].push(newObj); // ... push newObj into that sub-array
else // otherwise...
res[key] = [ newObj ]; // ... create a new sub-array for this key that initially contain newObj
return res;
}, {});
}
var result = group([
{time: "t1", locA: "a1", locB: "b1", value: "v1"},
{time: "t1", locA: "a1", locB: "b2", value: "v2"},
{time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"},
{time: "t2", locA: "a1", locB: "b1", value: "v5"},
{time: "t2", locA: "a1", locB: "b2", value: "v6"},
{time: "t2", locA: "a2", locB: "b1", value: "v7"},
{time: "t2", locA: "a2", locB: "b2", value: "v8"}
]);
console.log(result);
Note: Instead of assigning the values to separate variables a1b1
, a1b2
, ... (which won't be very flexible and dynamic), my answer groups the results into one big object that contain the arrays (results) under their equivalent keys. So result
is like this:
注意:我没有将值分配给单独的变量a1b1,a1b2,...(这将不是非常灵活和动态),我的答案将结果分组为一个大对象,其中包含其等效键下的数组(结果)。所以结果是这样的:
result = {
"a1b1": [ ... ],
"a1b2": [ ... ],
...
}
#4
0
using lodash _.keyBy you can split it on the bases of key. link to the function https://lodash.com/docs/4.17.4#keyBy .
使用lodash _.keyBy你可以在key的基础上拆分它。链接到功能https://lodash.com/docs/4.17.4#keyBy。
#5
0
I assumed the values are ordered by time in the original data set. Then it is just a matter of collating the data.
我假设这些值按原始数据集中的时间排序。然后只是整理数据的问题。
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: 'v1'},
{time: "t1", locA: "a1", locB: "b2", value: 'v2'},
{time: "t1", locA: "a2", locB: "b1", value: 'v3'},
{time: "t1", locA: "a2", locB: "b2", value: 'v4'},
{time: "t2", locA: "a1", locB: "b1", value: 'v5'},
{time: "t2", locA: "a1", locB: "b2", value: 'v6'},
{time: "t2", locA: "a2", locB: "b1", value: 'v7'},
{time: "t2", locA: "a2", locB: "b2", value: 'v8'}
];
// The key for an item is locA joined with locB.
function getItemKey(item) {
return item.locA + item.locB;
}
// Method for transforming an item into the desired data structure.
function transformItem(item) {
return {
loc: getItemKey(item),
time: item.time,
value: item.value
};
}
// Method for collating the dataset so items with a matching locA / locB are grouped together.
function collateLocationData(dataSet) {
const
resultMap = new Map();
// Iterate over the data set.
dataSet.forEach(item => {
const
// Get the key for current item.
itemKey = getItemKey(item);
// Check if the key exists in the map...
if (resultMap.has(itemKey)) {
// ... and when it does add the transformed item to the key's value.
resultMap.get(itemKey).push(transformItem(item));
} else {
// ... and when it doesn't add the key to the map with the transformed item.
resultMap.set(itemKey, [transformItem(item)]);
}
});
// Return the map.
return resultMap;
}
const
collatedData = collateLocationData(dataset);
/* === LOGGING THE MAP TO THE CONSOLE === */
function itemToString(items) {
return items.reduce((html, item) => {
if (html !== '' ) {
html += ' || ';
}
return html + `loc: ${item.loc} / time: ${item.time} / value: ${item.value}`;
}, '');
}
collatedData.forEach((values, key) => {
console.log(`${key} = ${itemToString(values)}`);
});
#1
2
Another short Array.prototype.reduce()
approach:
另一个简短的Array.prototype.reduce()方法:
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: "v1"}, {time: "t1", locA: "a1", locB: "b2", value: "v2"}, {time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"}, {time: "t2", locA: "a1", locB: "b1", value: "v5"}, {time: "t2", locA: "a1", locB: "b2", value: "v6"}, {time: "t2", locA: "a2", locB: "b1", value: "v7"}, {time: "t2", locA: "a2", locB: "b2", value: "v8"}
];
var result = dataset.reduce(function(r, o){
var k = o.locA + o.locB; // unique `loc` key
if (r[k] || (r[k]=[])) r[k].push({loc:k, time: o.time, value: o.value});
return r;
}, {});
console.log(result);
#2
1
Something like this?
像这样的东西?
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: 0},
{time: "t1", locA: "a1", locB: "b2", value: 1},
{time: "t1", locA: "a2", locB: "b1", value: 2},
{time: "t1", locA: "a2", locB: "b2", value: 3},
{time: "t2", locA: "a1", locB: "b1", value: 4},
{time: "t2", locA: "a1", locB: "b2", value: 5},
{time: "t2", locA: "a2", locB: "b1", value: 6},
{time: "t2", locA: "a2", locB: "b2", value: 7}
];
var result = {};
dataset
.sort((a, b) => {
return Number(a.time.replace(/\D/g, '')) > Number(b.time.replace(/\D/g, ''));
})
.forEach(d => {
var key = d.locA + d.locB;
if (!result[key]) {
result[key] = [];
}
result[key].push({
loc: key,
time: d.time,
value: d.value
});
});
console.log(result);
If you really want to create vars like var a1b1
instead of an object as result, replace result[key]
with window[key]
inside the loop.
如果你真的想要创建变量如var a1b1而不是对象作为结果,请在循环内用window [key]替换result [key]。
#3
1
You can use reduce
to group the objects:
您可以使用reduce对对象进行分组:
function group(arr) {
return arr.reduce(function(res, obj) { // for each object obj in the array arr
var key = obj.locA + obj.locB; // let key be the concatination of locA and locB
var newObj = {loc: key, time: obj.time, value: obj.value}; // create a new object based on the object obj
if(res[key]) // if res has a sub-array for the current key then...
res[key].push(newObj); // ... push newObj into that sub-array
else // otherwise...
res[key] = [ newObj ]; // ... create a new sub-array for this key that initially contain newObj
return res;
}, {});
}
var result = group([
{time: "t1", locA: "a1", locB: "b1", value: "v1"},
{time: "t1", locA: "a1", locB: "b2", value: "v2"},
{time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"},
{time: "t2", locA: "a1", locB: "b1", value: "v5"},
{time: "t2", locA: "a1", locB: "b2", value: "v6"},
{time: "t2", locA: "a2", locB: "b1", value: "v7"},
{time: "t2", locA: "a2", locB: "b2", value: "v8"}
]);
console.log(result);
Note: Instead of assigning the values to separate variables a1b1
, a1b2
, ... (which won't be very flexible and dynamic), my answer groups the results into one big object that contain the arrays (results) under their equivalent keys. So result
is like this:
注意:我没有将值分配给单独的变量a1b1,a1b2,...(这将不是非常灵活和动态),我的答案将结果分组为一个大对象,其中包含其等效键下的数组(结果)。所以结果是这样的:
result = {
"a1b1": [ ... ],
"a1b2": [ ... ],
...
}
#4
0
using lodash _.keyBy you can split it on the bases of key. link to the function https://lodash.com/docs/4.17.4#keyBy .
使用lodash _.keyBy你可以在key的基础上拆分它。链接到功能https://lodash.com/docs/4.17.4#keyBy。
#5
0
I assumed the values are ordered by time in the original data set. Then it is just a matter of collating the data.
我假设这些值按原始数据集中的时间排序。然后只是整理数据的问题。
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: 'v1'},
{time: "t1", locA: "a1", locB: "b2", value: 'v2'},
{time: "t1", locA: "a2", locB: "b1", value: 'v3'},
{time: "t1", locA: "a2", locB: "b2", value: 'v4'},
{time: "t2", locA: "a1", locB: "b1", value: 'v5'},
{time: "t2", locA: "a1", locB: "b2", value: 'v6'},
{time: "t2", locA: "a2", locB: "b1", value: 'v7'},
{time: "t2", locA: "a2", locB: "b2", value: 'v8'}
];
// The key for an item is locA joined with locB.
function getItemKey(item) {
return item.locA + item.locB;
}
// Method for transforming an item into the desired data structure.
function transformItem(item) {
return {
loc: getItemKey(item),
time: item.time,
value: item.value
};
}
// Method for collating the dataset so items with a matching locA / locB are grouped together.
function collateLocationData(dataSet) {
const
resultMap = new Map();
// Iterate over the data set.
dataSet.forEach(item => {
const
// Get the key for current item.
itemKey = getItemKey(item);
// Check if the key exists in the map...
if (resultMap.has(itemKey)) {
// ... and when it does add the transformed item to the key's value.
resultMap.get(itemKey).push(transformItem(item));
} else {
// ... and when it doesn't add the key to the map with the transformed item.
resultMap.set(itemKey, [transformItem(item)]);
}
});
// Return the map.
return resultMap;
}
const
collatedData = collateLocationData(dataset);
/* === LOGGING THE MAP TO THE CONSOLE === */
function itemToString(items) {
return items.reduce((html, item) => {
if (html !== '' ) {
html += ' || ';
}
return html + `loc: ${item.loc} / time: ${item.time} / value: ${item.value}`;
}, '');
}
collatedData.forEach((values, key) => {
console.log(`${key} = ${itemToString(values)}`);
});