// 元データ
[
{ name: 'taro', age: 10 },
{ name: 'jiro', age: 20, email: 'jiro@example.com' },
{ name: 'saburo', age: 30, email: 'saburo@example.com' }
]
// 欲しいデータ(ユーザごとではなくそれぞれのフィールドでグルーピングしたい)
{
name: ['taro', 'jiro', 'saburo'],
age: [10, 20, 30],
email: ['jiro@example.com', 'saburo@example.com']
}
このようにデータを変換するため、lodash(underscore.js)、ES2015(ES6)、ES5のそれぞれの実装方法をまとめる。
オブジェクトの配列をKeyで集成(グルーピング)する
lodash(underscore.js)が使える場合
const target = [
{
name: 'taro',
age : 10
},
{
name : 'jiro',
age : 20,
email: 'jiro@example.com'
},
{
name : 'saburo',
age : 30,
email: 'saburo@example.com'
}
]
const tallyTarget = target => {
// ObjectからKeyを重複なく取得
const keys = _.uniq(_.flatten(target.map(t => Object.keys(t))))
// keyで抽出する(pluck)
const result = {}
keys.forEach(k => result[k] = _.compact(_.map(target, k)))
return result
}
// {
// name : ['taro', 'jiro', 'saburo'],
// age : [10, 20, 30],
// email: ['jiro@example.com', 'saburo@example.com']
// }
console.log(tallyTarget(target))
ライブラリを使わずES2015(ES6)で書く場合
const tallyTarget = target => {
// flatten
const _keys = target.map(a => Object.keys(a)).reduce((a, b) => a.concat(b))
// unique
const keys = Array.from(new Set(_keys))
const result = {}
keys.forEach(k => {
// pluck & compact
result[k] = target.map(t => t[k]).filter(t => !!t)
})
return result
}
ちょっと古いブラウザを対応する場合
Internet Explorer 11など最新のブラウザなら問題ないのだが、IE9以前は闇すぎるので対象外とする。(IE9以前も対応するならライブラリを使うのが賢明)ES2015とかわる部分は重複排除の部分。
var tallyTarget = function (target) {
// flatten
var _keys = target.map(function (a) {
return Object.keys(a);
}).reduce(function (a, b) {
return a.concat(b);
});
// unique
var keys = _keys.filter(function (a, i, self) {
return self.indexOf(a) === i;
});
var result = {};
keys.forEach(function (k) {
// pluck & compact
result[k] = target.map(function (t) {
return t[k];
}).filter(function (t) {
return !!t;
});
});
return result;
};
参考サイト
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿