2017-12-08 16 views
0

Map、Filter、Reduceなどの高次関数を使いたかったのです。
私の問題は整理されていない配列があるため、私が望む結果を得るためにループ操作を実行しなければならなかったことです。配列には_idtotalCountの2つのフィールドがあり、配列は長さが最小0から3になります。
totalCount各反復は2つのフィールドで構成されます.1つはorderstatusで、もう1つは合計です。else if else if normal orderstatusは "Merchant"または "driver"または "user"です。その反復合計を受け取り、MerchantCountのような配列に格納したいと思います。2つのループの代わりに高次関数を使用する

これは私のコードです:

var arr = [{ 
    _id: "2017-12-08", 
    totalcount: [{ 
    orderstatus: "MERCHANT", 
    total: 1 
    }] 
}, 
{ 
    _id: "2017-12-02", 
    totalcount: [{ 
    orderstatus: "USER", 
    total: 2 
    }] 
}, 
{ 
    _id: "2017-12-06", 
    totalcount: [{ 
    orderstatus: "DRIVER", 
    total: 1 
    }] 
}, 
{ 
    _id: "2017-12-07", 
    totalcount: [{ 
    orderstatus: "MERCHANT", 
    total: 3 
    }] 
}, 
{ 
    _id: "2017-12-04", 
    totalcount: [{ 
     orderstatus: "DRIVER", 
     total: 1 
    }, 
    { 
     orderstatus: "MERCHANT", 
     total: 2 
    }, 
    { 
     orderstatus: "USER", 
     total: 1 
    } 
    ] 
} 
] 

ループが行っております:

for (let i = 0; i < recentUserCount.length; i++) { 
    for (let j = 0; j < recentUserCount[i].totalcount.length; j++) { 
    if (recentUserCount[i].totalcount[j].usertype == "DRIVER") { 
     recentUserCount[i].DRIVERCount = recentUserCount[i].totalcount[j].total; 
    } else if (recentUserCount[i].totalcount[j].usertype == "USER") { 
     recentUserCount[i].USERCount = recentUserCount[i].totalcount[j].total; 
    } else if (recentUserCount[i].totalcount[j].usertype == "MERCHANT") { 
     recentUserCount[i].MERCHANTCount = recentUserCount[i].totalcount[j].total; 
    } 
    } 
} 

を結果はおおよそ以下のようになります。

0 : {_id: "2017-12-08", totalcount: Array(1), MERCHANTCount: 3, $$hashKey: "object:316"} 
    1 : {_id: "2017-12-07", totalcount: Array(1), MERCHANTCount: 3, $$hashKey: "object:317"} 
    2 : {_id: "2017-12-06", totalcount: Array(1), DRIVERCount: 1, $$hashKey: "object:318"} 
    3 : {_id: "2017-12-04", totalcount: Array(3), DRIVERCount: 1, MERCHANTCount: 2, USERCount: 1, …} 

私は同じ操作になりたいですMap/FilterまたはReduceメソッドを使用して実行されます。

+0

なぜ 'map' /' reduce'を使ってみたいのですが、あなたのコードをどのように改善すると思いますか? – Bergi

+1

@Bergiコードを改善するかどうかは分かりません。これで高次関数を試してみただけです – Kannan

+0

コードには副作用があります(既存のオブジェクトにフィールドを追加する)。 'for ... of'ループを使って単純化することもできますし、NinaScholzの答えのように' if'カスケードの代わりに動的プロパティ名を使うこともできます。 – Bergi

答えて

4

、 FUL L官能スニペット:

var arr = [{_id:"2017-12-08",totalcount:[{orderstatus:"MERCHANT",total:1}]},{_id:"2017-12-02",totalcount:[{orderstatus:"USER",total:2}]},{_id:"2017-12-06",totalcount:[{orderstatus:"DRIVER",total:1}]},{_id:"2017-12-07",totalcount:[{orderstatus:"MERCHANT",total:3}]},{_id:"2017-12-04",totalcount:[{orderstatus:"DRIVER",total:1},{orderstatus:"MERCHANT",total:2},{orderstatus:"USER",total:1}]}]; 
 

 
    const result = arr 
 
     .map(({_id, totalcount}) => ({ 
 
     totalcount, 
 
     _id, 
 
     ...totalcount.reduce((acc, {orderstatus, total}) => 
 
      ({...acc, [`${orderstatus}count`]: total}), {}) 
 
     })) 
 

 
console.log(result)

https://jsbin.com/kiwalozuxa/edit?html,js,console,output

EDIT:The spread operator(...)(アレイのまたは値)キー/オブジェの値を拡散するために使用されます。

{ 
    a: "a", 
    b: "b", 
    { 
    x: "x", 
    y: "y" 
    } 
} 

は私が親に私の「子」オブジェクトをマージするスプレッド演算子を使用します。それは、このフォームのオブジェを持つようにJavaScriptで技術的に有効ではありませんので

{ 
    x: "x", 
    y: "y" 
} 

totcalcount.reduceは、ここにオブジェクトを返しますオブジェと生産:

{ 
    a: "a", 
    b: "b", 
    x: "x", 
    y: "y" 
} 

私はレデューサーで同じ技術を使用します。

+0

これは完璧に動作しますが、私はあなたのコードを理解できませんでしたが、それは... totalcountのinfrontですか?これについて説明していただけますか?おかげで – Kannan

+0

はい、私はできるだけ早く編集 – Epitouille

0

2つのネストされたforEachループに縮小し、orderstatusを新しいプロパティの一部として使用できます。

var totalReference = { MERCHANT: 'MERCHANTCount', USER: 'USERCount', DRIVER: 'DRIVERCount' }, 
 
    array = [{ _id: "2017-12-08", totalcount: [{ orderstatus: "MERCHANT", total: 1 }] }, { _id: "2017-12-02", totalcount: [{ orderstatus: "USER", total: 2 }] }, { _id: "2017-12-06", totalcount: [{ orderstatus: "DRIVER", total: 1 }] }, { _id: "2017-12-07", totalcount: [{ orderstatus: "MERCHANT", total: 3 }] }, { _id: "2017-12-04", totalcount: [{ orderstatus: "DRIVER", total: 1 }, { orderstatus: "MERCHANT", total: 2 }, { orderstatus: "USER", total: 1 }] }]; 
 

 
array.forEach(function (o) { 
 
    o.totalcount.forEach(function (p) { 
 
     if (totalReference[p.orderstatus]) { 
 
      o[totalReference[p.orderstatus]] = p.total; 
 
     } 
 
    }); 
 
}); 
 

 
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1

私が軽減し、割り当てたいこと

let res = arr.reduce((a, b) => { 
    let totals = b.totalcount.reduce((x, y) => { 
     x[y.orderstatus + 'Count'] = (x[y.orderstatus + 'Count'] || 0) + y.total; 
     return x; 
    }, {}); 
    return a.concat(Object.assign(b, totals)); 
}, []); 

var arr = [{_id:"2017-12-08",totalcount:[{orderstatus:"MERCHANT",total:1}]},{_id:"2017-12-02",totalcount:[{orderstatus:"USER",total:2}]},{_id:"2017-12-06",totalcount:[{orderstatus:"DRIVER",total:1}]},{_id:"2017-12-07",totalcount:[{orderstatus:"MERCHANT",total:3}]},{_id:"2017-12-04",totalcount:[{orderstatus:"DRIVER",total:1},{orderstatus:"MERCHANT",total:2},{orderstatus:"USER",total:1}]}]; 
 

 
let res = arr.reduce((a, b) => { 
 
    let totals = b.totalcount.reduce((x, y) => { 
 
     x[y.orderstatus + 'Count'] = (x[y.orderstatus + 'Count'] || 0) + y.total; 
 
     return x; 
 
    }, {}); 
 
    return a.concat(Object.assign(b, totals)); 
 
}, []); 
 

 
console.log(res);
ES6の構文とマップ/削減とかなり簡単

関連する問題