質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

4回答

4448閲覧

JavaScriptで、プロパティ値をもとにオブジェクトをソートしたい

tamogi

総合スコア72

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2018/07/27 02:07

前提・実現したいこと

あるサービスのAPIを叩くと、以下のようなレスポンスが返ってきます。

javascript

1{ 2 "hoge": { 3 "val": "val1", 4 "index": 1 5 }, 6 "piyo": { 7 "val": "val3", 8 "index": 3 9 }, 10 "fuga": { 11 "val": "val5", 12 "index": 5 13 }, 14 "foo": { 15 "val": "val2", 16 "index": 2 17 }, 18 "bar": { 19 "val": "val4", 20 "index": 4 21 } 22}

毎回順番がランダムで取得されるので、indexプロパティの昇順でソートしたいです。

試したこと

配列を用意し、indexの値をそのまま配列の添字に設定することで、ソート自体は出来ました。

ただし、2回ループしないといけないので書き方がダサいのと、keyの値が欲しくなった時に別途考慮しないといけないので、もう少しスマートな書き方があれば教えてください。

javascript

1var apiResult = {...}; // 上記のオブジェクト 2 3// 並び替え後の配列 4var sortedArray = []; 5 6// 並び替える 7for (var key in apiResult) { 8 // sortedArrayの添字にindexプロパティ値を設定 9 sortedArray[apiResult[key]["index"]] = apiResult[key]; 10} 11 12//確認 13console.log(sortedArray); 14// 1:{ val: "val1", index: 1 } 15// 2:{ val: "val2", index: 2 } 16// 3:{ val: "val3", index: 3 } 17// 4:{ val: "val4", index: 4 } 18// 5:{ val: "val5", index: 5 } 19 20// 出力 21for (var i = 1; i < sortedArray.length; i++) { 22 console.log(sortedArray[i].val); 23}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

{} のプロパティに順番はない

{} が持つプロパティに順番という概念はありません。
順番に意味があるなら、配列や new Map のようなiterableなオブジェクトが必要です。

JavaScript

1new Map(Object.entries(object).sort(function (a, b) { 2 // ソート処理 3}));

クロスブラウザはPolyfillで対応して下さい。

Map.prototype.sort

一度、定義した new Map を再ソートする方法が標準で用意されていない為、再ソートには工夫が必要です。
https://gist.github.com/think49/daaf5ee0a4f12092862c81c54747bae5

Re: tamogi さん

投稿2018/07/27 03:33

think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こういうのは使う直前で用意するものです。
そしてJavaScriptにはメソッドチェーンで値を加工することが出来るので、
ObjectやArrayに紐づくメソッドをしっかり覚えれば数行で終わります。

例えば「indexプロパティの昇順でソート」されたものを画面表示するならばこう。

JavaScript

1var apiResult = { 2 hoge: {val: "val1", index: 1}, 3 piyo: {val: "val3", index: 3}, 4 fuga: {val: "val5", index: 5}, 5 foo: {val: "val2", index: 2}, 6 bar: {val: "val4", index: 4} 7}; 8 9Object.values(apiResult) 10 .sort((a, b) => a.index - b.index) 11 .forEach(it => console.log(it.val)); 12// val1, val2, val3, val4, val5の順に出力

また、初期状態でkey: valueのオブジェクトになっていますが、
JS側からは使いにくいケースがありますので、
下記の様にオブジェクトの配列に変換して記憶させておくのも良いかもしれませんね。

この辺は一長一短なのでどちらで持つかは実装と好みみたいなもんです。
key: "hoge"で検索する頻度が高くなければ、
MySQLなんかのRDBは基本的に2次元の表形式なのでオブジェクトの配列として持っておくと分かりやすいかと思います。

JavaScript

1var apiResult = { 2 hoge: {val: "val1", index: 1}, 3 piyo: {val: "val3", index: 3}, 4 fuga: {val: "val5", index: 5}, 5 foo: {val: "val2", index: 2}, 6 bar: {val: "val4", index: 4} 7}; 8 9var newResult = Object.keys(apiResult) 10 .sort((a, b) => apiResult[a].index - apiResult[b].index) 11 .map(key => ({key, ...apiResult[key]})); 12console.log(newResult); 13// [ 14// {key: "hoge", val: "val1", index: 1}, 15// {key: "foo", val: "val2", index: 2}, 16// {key: "piyo", val: "val3", index: 3}, 17// {key: "bar", val: "val4", index: 4}, 18// {key: "fuga", val: "val5", index: 5} 19// ] 20 21// key: piyoを得たい 22console.log(newResult.find(it => it.key === 'piyo')); 23// {key: "piyo", val: "val3", index: 3}

投稿2018/07/27 03:52

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

ソート後のデータ構造をどのように持つのか、用途によっていろいろ考えられそうですが、一例としてこの回答では、元のJSONから以下のような形のオブジェクト

javascript

1{ key: "hoge", val:"val1", index:1 }

を要素とする配列を、

によって作成し、これを index の値の昇順になるように、

を使ってソートします。以下がそのコードです。

javascript

1const jsonString = `{ 2 "hoge": { 3 "val": "val1", 4 "index": 1 5 }, 6 "piyo": { 7 "val": "val3", 8 "index": 3 9 }, 10 "fuga": { 11 "val": "val5", 12 "index": 5 13 }, 14 "foo": { 15 "val": "val2", 16 "index": 2 17 }, 18 "bar": { 19 "val": "val4", 20 "index": 4 21 } 22}`; 23 24const dataObj = JSON.parse(jsonString); 25 26const sortedAry = 27 Object.entries(dataObj) 28 .map(([key, data]) => ({ key, ...data })) 29 .sort((e1, e2) => e1.index - e2.index ); 30 31console.log(JSON.stringify(sortedAry, null, "\t"));

※上記のコードと同じものを、https://jsfiddle.net/jun68ykt/g956j2fn/39/ にも上げました。

これを実行すると、以下が出力されます。

JSON

1[ 2 { 3 "key": "hoge", 4 "val": "val1", 5 "index": 1 6 }, 7 { 8 "key": "foo", 9 "val": "val2", 10 "index": 2 11 }, 12 { 13 "key": "piyo", 14 "val": "val3", 15 "index": 3 16 }, 17 { 18 "key": "bar", 19 "val": "val4", 20 "index": 4 21 }, 22 { 23 "key": "fuga", 24 "val": "val5", 25 "index": 5 26 } 27]

以上参考になれば幸いです。


補足

プレーンオブジェクトのプロパティに順序がないことについては、以下の投稿で確認されるとよいかと思います。

上記、質問の回答の中で一番得票の多い回答 では、 ECMAScript Third Edition (pdf) からの引用で、以下が書かれています。

4.3.3 Object

An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.


補足2

think49さんがご回答で、og24715さんがコメントで、それぞれご提案されている Map を使ったコードを示します。for ... of を使ったときに、index の値の昇順に内容を列挙するようなMapオブジェクトを作成するには、以下のようにします。

javascript

1const sortedEntriesByIndex = Object.entries(dataObj).sort(([key1, data1], [key2, data2]) => data1.index - data2.index); 2 3const map = new Map(sortedEntriesByIndex); 4

上記のサンプル: https://jsfiddle.net/jun68ykt/jug198we/3/

投稿2018/07/27 02:33

編集2018/07/28 00:52
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

投稿2018/07/27 02:19

og24715

総合スコア832

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamogi

2018/07/27 02:28

結局1回は配列にしないといけないということですね。
yambejp

2018/07/27 02:37

> 1回は配列にしないといけない いえ、順番を持っているのは配列だけで、オブジェクトの要素に 順番をつけることはできないということです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問