オブジェクトのキー順ソート(新規オブジェクト作成)の基本と実践
「オブジェクトのプロパティをキー順に並べ替えて扱いたい」時は、キーを配列にしてソートし、reduceで新しいオブジェクトを組み立てます。元のオブジェクトはそのまま、新しい“並び替え済み”オブジェクトを作るのが安全です。
基本パターン(昇順)
const obj = { c: 3, a: 1, b: 2 };
const sorted = Object.keys(obj)
.sort() // "a", "b", "c"
.reduce((acc, k) => {
acc[k] = obj[k];
return acc;
}, {});
console.log(sorted); // { a: 1, b: 2, c: 3 }
JavaScript- 流れ: keys → sort → reduce(新規作成)。
- 不変: 元オブジェクトは変更しない(再構築)。
よく使うテンプレート集
1) 降順(Z→A)
const obj = { c: 3, a: 1, b: 2 };
const desc = Object.keys(obj)
.sort((x, y) => y.localeCompare(x))
.reduce((acc, k) => (acc[k] = obj[k], acc), {});
console.log(desc); // { c: 3, b: 2, a: 1 }
JavaScript- ポイント:
localeCompareは文字列の比較に便利。単純なsort().reverse()でもOK。
2) 日本語や大小文字を意識したソート(ロケール比較)
const names = { さくら: 1, あや: 2, カナ: 3 };
const sorted = Object.keys(names)
.sort((a, b) => a.localeCompare(b, "ja"))
.reduce((acc, k) => (acc[k] = names[k], acc), {});
console.log(sorted); // ロケールに沿った並び
JavaScript- ポイント: 言語依存の並びが欲しいときは
localeCompare(b, "ja")のようにロケール指定。
3) 数値っぽいキーを数値としてソート
const obj = { "10": "x", "2": "y", "1": "z" };
const numeric = Object.keys(obj)
.sort((a, b) => Number(a) - Number(b))
.reduce((acc, k) => (acc[k] = obj[k], acc), {});
console.log(numeric); // { "1": "z", "2": "y", "10": "x" }
JavaScript- ポイント: 文字列キーを数値に変換して比較すると、直感的な数値順になる。
4) カスタム順(優先キーを決める)
const obj = { beta: 2, gamma: 3, alpha: 1, misc: 9 };
const order = ["alpha", "beta", "gamma"]; // これを優先
const custom = Object.keys(obj)
.sort((a, b) => {
const ia = order.indexOf(a), ib = order.indexOf(b);
if (ia !== -1 && ib !== -1) return ia - ib; // 両方定義済み
if (ia !== -1) return -1; // aだけ優先
if (ib !== -1) return 1; // bだけ優先
return a.localeCompare(b); // 残りは名前順
})
.reduce((acc, k) => (acc[k] = obj[k], acc), {});
console.log(custom); // { alpha:1, beta:2, gamma:3, misc:9 }
JavaScript5) 値を基準にソート(キーではなく値)
const obj = { a: 30, b: 10, c: 20 };
const byValue = Object.keys(obj)
.sort((x, y) => obj[x] - obj[y]) // 値の昇順
.reduce((acc, k) => (acc[k] = obj[k], acc), {});
console.log(byValue); // { b:10, c:20, a:30 }
JavaScript実務で便利なヘルパー関数
function sortObjectKeys(source, comparator = (a, b) => a.localeCompare(b)) {
return Object.keys(source)
.sort(comparator)
.reduce((acc, k) => (acc[k] = source[k], acc), {});
}
// 使い方
const o = { c: 3, a: 1, b: 2 };
console.log(sortObjectKeys(o)); // キー名昇順
console.log(sortObjectKeys(o, (a, b) => b.localeCompare(a))); // 降順
JavaScript- ポイント: 比較関数を差し替えれば、数値順・カスタム順・値基準などに対応できる。
よくある落とし穴と対策
- Symbolキーや非列挙プロパティが含まれない:
Object.keysは「自前の列挙可能な文字列キー」のみ。- 対策: 必要なら
Object.getOwnPropertySymbolsやObject.getOwnPropertyNamesを併用し、結合してから並べ替える。
- 対策: 必要なら
- 元の順序を過信しない: オブジェクトの表示順は仕様ルールがあるが、UI要件に合わせたいなら「自分で keys を並べて再構築」する。
- 対策: 本テンプレートのように新オブジェクトを作る。
- 数値文字列の並びが直感的でない: 文字列比較では
"10"が"2"より前後でブレる。- 対策:
Number(a) - Number(b)で数値比較。
- 対策:
- パフォーマンス: 巨大オブジェクトで頻繁に並べ替えるとコスト大。
- 対策: キャッシュ・一度だけ構築・差分更新の検討。
- 深いネストは対象外: この手法は“トップレベルのキー並べ替え”。
- 対策: ネスト内も並べ替えたいなら、再帰的に適用するヘルパーを用意する。
練習問題(手を動かして覚える)
// 1) 基本のキー昇順
const o1 = { d: 4, b: 2, a: 1, c: 3 };
console.log(Object.keys(o1).sort().reduce((acc, k) => (acc[k] = o1[k], acc), {}));
// 2) 数値キーを数値順に
const o2 = { "10": "x", "2": "y", "1": "z" };
console.log(Object.keys(o2).sort((a, b) => Number(a) - Number(b))
.reduce((acc, k) => (acc[k] = o2[k], acc), {}));
// 3) 値の降順で並べ替え
const o3 = { a: 30, b: 10, c: 20 };
console.log(Object.keys(o3).sort((x, y) => o3[y] - o3[x])
.reduce((acc, k) => (acc[k] = o3[k], acc), {}));
// 4) カスタム順(定義にないキーは名前昇順)
const o4 = { beta: 2, misc: 9, gamma: 3, alpha: 1 };
const order = ["alpha", "beta", "gamma"];
console.log(Object.keys(o4).sort((a, b) => {
const ia = order.indexOf(a), ib = order.indexOf(b);
if (ia !== -1 && ib !== -1) return ia - ib;
if (ia !== -1) return -1;
if (ib !== -1) return 1;
return a.localeCompare(b);
}).reduce((acc, k) => (acc[k] = o4[k], acc), {}));
JavaScript直感的な指針
- 並べ替えは「キー配列」をソートして「新オブジェクト」に戻す。
- 文字列順なら
sort()/ロケール重視ならlocaleCompare。 - 数値キーは数値比較で直感的な並びに。
- 要件に合わせた比較関数を作って再利用。
