2017-09-04 74 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)}`); 
 
});