2017-09-04 58 views
4

我有这样一个数据集对象,以多个阵列分割阵列:基于独特的组合

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 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"}, 
.... 
]; 

的T值是很重要正确的顺序,而它代表时间。我无法使用库,只是复古的JavaScript。我发现了一些较旧的SO帖子,它们分割了一组对象,但它们只描述了简单的分割或使用库。

是否有可能用foreach像

dataset.forEach(function()... 

任何帮助表示赞赏..

回答

2

另一个短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);

1

您可以使用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);

注:分配值给独立的变量a1b1a1b2相反的,...(不会非常灵活和动态),我的答案将结果分组到一个大对象中,该对象包含相同键下的数组(结果)。所以result是这样的:

result = { 
    "a1b1": [ ... ], 
    "a1b2": [ ... ], 
    ... 
} 
1

是这样的吗?

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);

如果你真的想创造瓦尔像var a1b1,而不是一个对象作为结果,与window[key]内循环替换result[key]

0

我假设这些值按原始数据集中的时间排序。那么这只是一个整理数据的问题。

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)}`); 
 
});