2017-10-18 16 views
1

私は現在、多次元配列を平坦化するための関数をマップし、縮小しようとしています。
これはモック例データセットである:多次元配列を減らす

data.map(sort => sort.data.reduce((a,b) => a.weight + b.weight)); 

しかし、私が代わりに月単位で削減したい:私はマップ-減らすために、私が使用することができ、ソート番号順に知っ

data: [ 
    { 
    label: "Sort-01" 
    data: [ 
     { 
     label: "OCT-2017" 
     weight: 2304 
     }, 
     { 
     label: "NOV-2017" 
     weight: 1783 
     } 
    ] 
    }, 
    { 
    label: "Sort-02" 
    data: [ 
     { 
     label: "OCT-2017" 
     weight: 4785 
     }, 
     { 
     label: "NOV-2017" 
     weight: 102 
     } 
    ] 
    }, 
...... 
] 

ソート番号。
助けていただければ幸いです。

おかげで、
ジェイ

答えて

2

使用アレイ#マップArray#concatspreadで平らその後、dataプロパティ配列の配列を取得します。

const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}]; 
 

 
const helper = Object.create(null); 
 
const result = [].concat.apply([], array.map(({ data }) => data)) // map the array into an array of data arrays, and flatten by apply concat 
 
    .reduce((r, { label, weight }) => { 
 
    // if label is not in helper, add to helper, and push to r 
 
    if(!helper[label]) { 
 
     helper[label] = { label, weight: 0 }; 
 
     r.push(helper[label]); 
 
    } 
 
    
 
    helper[label].weight += weight; // add the weight to the object 
 
    
 
    return r; 
 
    }, []) // get the values iterator 
 

 
console.log(result);

const array = [{"label":"Sort-01","data":[{"label":"OCT-2017","weight":2304},{"label":"NOV-2017","weight":1783}]},{"label":"Sort-02","data":[{"label":"OCT-2017","weight":4785},{"label":"NOV-2017","weight":102}]}]; 
 

 
const result = [... // spread the values iterator to an array 
 
    [].concat(...array.map(({ data }) => data)) // map the array into an array of data arrays 
 
    .reduce((m, { label, weight }) => { 
 
    // take item if label exists in map, if not create new 
 
    const item = m.get(label) || { label, weight: 0 }; 
 
    
 
    item.weight += weight; // add the weight 
 
    
 
    return m.set(label, item); // set the item in the map 
 
    }, new Map).values()] // get the values iterator 
 

 
console.log(result);
ここ

がspreadlessバージョンである:配列に戻って変換することMap#values、およびスプレッド構文を使用し、その後、Mapに値を収集するためにArray#reduceを使用して、

+0

普及せずにこれを行う方法はありますか?私が現在取り組んでいるプロジェクトではまだ事業者が広がっていないと思います。私は "[]] .concat.apply(...)を取得しています。reduce(...)values(...)。sliceは関数のエラーではありません。 – Jay

+0

私は、スプレッドなしのMapとMapを追加しました。 –

1

reduceまたはconcat (see Ori's answer)を使用すると、フラット化されたデータ配列を取得できます。そこから、あなたの年ラベルをキーとして再割り当てし、重さを価値として再割り当てします。 次に、あなたの体重を月ごとに合計するために、別の減量措置に渡します。

const data = [{label: "Sort-01",data: [{label: "OCT-2017",weight: 2304,},{label: "NOV-2017",weight: 1783,},],},{label: "Sort-02",data: [{label: "OCT-2017",weight: 4785,},{label: "NOV-2017",weight: 102,},],},]; 
 
const flatten = (acc, cur) => { 
 
    cur.data.forEach(val => acc.push(val)); 
 
    return acc; 
 
}; 
 
const monthMap = ({ label, weight }) => ({ [label]: weight }); 
 
const reducer = (acc, cur) => { 
 
    const key = Object.keys(cur)[0] 
 
    if (!acc.hasOwnProperty(key)) { acc[key] = 0 } 
 
    acc[key] += cur[key]; 
 
    return acc; 
 
}; 
 

 
let x = data.reduce(flatten, []).map(monthMap).reduce(reducer, {}); 
 
console.log(x);

+0

ありがとうございました! – Jay