はじめに
けっこうネストされた配列のいろんなsortに苦労したので忘れないようにメモしました。
前提
扱うJSONは下のような感じです。データは真面目に調べて作りましたが間違ってても許してください。(出典とか書いた方がいいのかな...)
※ 'generation'は、霜降り明星のせいやが言い出した'第7世代'とかいうよくわかんないあれです。
const office_list = [
{
'office':{
'office_name': '吉本興業(株)',
'comedian_num': 6000,
'members':[
{
'member_info':
{
'name': 'ダウンタウン',
'generation': 3,
'average_age': 55.5,
'entertainment_carrer': 37
}
},
{
'member_info':
{
'name': '明石家さんま',
'generation': 2,
'average_age': 64,
'entertainment_carrer': 45
}
},
{
'member_info':
{
'name': '霜降り明星',
'generation': 7,
'average_age': 26,
'entertainment_carrer': 6
}
}
]
}
},
{
'office':{
'office_name': 'ワタナベエンターテインメント',
'comedian_num': 170,
'members':[
{
'member_info':
{
'name': 'ネプチューン',
'generation': 4,
'average_age': 49.3,
'entertainment_carrer': 29
}
},
{
'member_info':
{
'name': '四千頭身',
'generation': 7,
'average_age': 22.0,
'entertainment_carrer': 3
}
},
{
'member_info':
{
'name': 'アンガールズ',
'generation': 6,
'average_age': 43.0,
'entertainment_carrer': 17
}
}
]
}
},
{
'office':{
'office_name': 'プロダクション人力舎',
'comedian_num': 70,
'members':[
{
'member_info':
{
'name': 'おぎやはぎ',
'generation': 5,
'average_age': 46.5,
'entertainment_carrer': 23
}
},
{
'member_info':
{
'name': 'オアシズ',
'generation': 4,
'average_age': 48.0,
'entertainment_carrer': 27
}
}
]
}
}
]
ソートいろいろ
最上位階層のキーでソート
事務所を芸人の所属人数の多い順にソート
office_list.sort((o, next_o) => {
return o.office.comedian_num > next_o.office.comedian_num ? -1 : 1
})
↓
office_list
[
{ office:
{ office_name: '吉本興業(株)', comedian_num: 6000, members: [Array] }
},
{ office:
{ office_name: 'ワタナベエンターテインメント', comedian_num: 170, members: [Array] }
},
{ office:
{ office_name: 'プロダクション人力舎', comedian_num: 70, members: [Array] }
}
]
逆順にしたかったら1と-1逆にするか不等号を反転
最上位でない階層のキーでソート
各事務所に対して芸人を芸歴の長い順にソート
※元のオブジェクト(office_list)の形式はそのまま
// 全事務所に対して
office_list.forEach((o) =>{
// 芸人を芸歴で降順ソート
o.office.members.sort((m, next_m) => {
return m.member_info.entertainment_carrer > next_m.member_info.entertainment_carrer ? -1 : 1
})
})
↓
office_list
// 長くなるので省略
全芸人を世代の新しい順にソート
※芸人の情報だけ取り出す
member_list = []
// メンバーのリストをつくって
office_list.forEach((o) =>{
member_list = member_list.concat(o.office.members.map(m => m.member_info))
})
// 降順にソート
member_list.sort((m, next_m)=>{
return m.generation > next_m.generation ? -1 : 1
})
↓
member_list
[
{ name: '四千頭身',
generation: 7,
average_age: 22,
entertainment_carrer: 3 },
{ name: '霜降り明星',
generation: 7,
average_age: 26,
entertainment_carrer: 6 },
{ name: 'アンガールズ',
generation: 6,
average_age: 43,
entertainment_carrer: 17 },
{ name: 'おぎやはぎ',
generation: 5,
average_age: 46.5,
entertainment_carrer: 23 },
{ name: 'オアシズ',
generation: 4,
average_age: 48,
entertainment_carrer: 27 },
{ name: 'ネプチューン',
generation: 4,
average_age: 49.3,
entertainment_carrer: 29 },
{ name: 'ダウンタウン',
generation: 3,
average_age: 55.5,
entertainment_carrer: 37},
{ name: '明石家さんま',
generation: 2,
average_age: 64,
entertainment_carrer: 45 }
]
なんかいけてないですけどいったんこれで
事務所を平均年齢の若い順にソート
※元のオブジェクト(office_list)の形式はそのまま
※新たに 'office_average_age' っていうプロパティをくっつけてみた
office_list.sort((o, next_o) =>{
o.office.office_average_age = o.office.members
.map(m => m.member_info.average_age) // 平均年齢だけ取り出して
.reduce((sum, each) => {
return sum += each
})/o.office.members.length // 合計/芸人数 で全芸人の平均年齢算出
next_o.office.office_average_age = next_o.office.members
.map(m => m.member_info.average_age)
.reduce((sum, each) => {
return sum += each
})/next_o.office.members.length
return o.office_average_age > next_o.office_average_age ? 1 : -1
})
↓
office_list
[
{ office:
{ office_name: '吉本興業(株)',
comedian_num: 6000,
members: [Array],
office_average_age: 48.5 }
},
{ office:
{ office_name: 'ワタナベエンターテインメント',
comedian_num: 170,
members: [Array],
office_average_age: 38.1 }
},
{ office:
{ office_name: 'プロダクション人力舎',
comedian_num: 70,
members: [Array],
office_average_age: 47.25 }
}
]
ここだけなぜか急に張り切って一発でソートするモードになってます
おわりに
ネストしてるとソートがなんだか厄介でした。最後のとか可読性考えると分けた方がよさそうな気がしますが自分の勉強のためにこれを載せました。以上です。