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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

JavaScript

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

Q&A

解決済

3回答

3494閲覧

JavaScriptで2次元配列をソートしたい

NyankoTaisa

総合スコア8

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

JavaScript

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

0グッド

2クリップ

投稿2020/02/20 09:07

JavaScriptで2次元配列をソートしたいです。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8"> 5 <title>test</title> 6 <script type="text/javascript" src="test.js"></script> 7</head> 8<body> 9 JavaScript ソートテスト 10</body> 11</html>

JavaScript

1// test.js 2window.onload = function(){ 3 var list = testSort([["aaa",10],["bbb",20],["ccc",""],["ddd",30],["eee",40]]); 4 console.log(list); 5 var list = testSort([["aaa",100],["bbb",10],["ccc",""],["ddd",30],["eee",40]]); 6 console.log(list); 7}; 8 9function testSort(list) { 10 list.sort(function(a, b){ 11 if (parseFloat(a[1]) > parseFloat(b[1])) return -1; 12 if (parseFloat(a[1]) < parseFloat(b[1])) return 1; 13 return 0; 14 }); 15 return list; 16}

JavaScript実行結果
JavaScript実行結果

[["文字列",数値]...["文字列",数値]]という内容の2次元配列を作成しました。
これを2番目の要素である数値の降順でソートしたいです。
もし、数値が空の場合は空の部分は一番後ろになるようにソートしたいです。

[["aaa",10],["bbb",20],["ccc",""],["ddd",30],["eee",40]]の場合は期待通り、
[["eee",40],["ddd",30],["bbb",20],["aaa",10],["ccc",""]]と、空の部分が最後になっています。

しかし、
[["aaa",100],["bbb",10],["ccc",""],["ddd",30],["eee",40]]の場合は、
[["aaa",100],["bbb",10],["ccc",""],["eee",40],["ddd",30]]となり、
空の位置が変化していません。
[["aaa",100],["eee",40],["ddd",30],["bbb",10],["ccc",""]]となるようにソートさせたいです。

2次元配列で、基本的には数値の降順でソートし、空白がある場合には、空白が最後になるようにソートするにはどのようにすればよろしいでしょうか?

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

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

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

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

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

guest

回答3

0

比較時に""を-Infinityに置き換えたらどうでしょうか.

javascript

1var comp = function(a, b) { 2 var _a = (a[1] === "") ? -Infinity : a[1]; 3 var _b = (b[1] === "") ? -Infinity : b[1]; 4 return (_b - _a); 5} 6var list = [["aaa",100],["bbb",10],["ccc",""],["ddd",30],["eee",40]].sort(comp); 7console.log(list);

追記
すみません、-Infinityから-Infinityを引くとNaNになっちゃいますね…
やはり

javascript

1var comp = function(a, b) { 2 if (a[1] === "") return 1; 3 if (b[1] === "") return -1; 4 return (b[1] - a[1]); 5}

が妥当でしょうか

投稿2020/02/20 09:36

編集2020/02/21 17:34
kairi003

総合スコア1332

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

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

kairi003

2020/02/20 09:45

負数が無いなら-1でもいいと思います
NyankoTaisa

2020/02/21 11:11

Infinity については知らなかったので、とても勉強になりました。 ありがとうございました!
guest

0

ベストアンサー

こんにちは

ご質問に挙げられているコードを改善する際には、以下の (1)、(2) の2点を使うとよいかと思います。

  • (1) 引き算の対象に空文字列があると、0 として扱われる。(以下、参照)
$ node Welcome to Node.js v12.7.0. Type ".help" for more information. > 100 - "" 100 > "" - 100 -100 >
  • (2) sort に与える関数の返す値として、1の替わりに正の数、-1 の替わりに負の数を返させる。

  

以下、具体的なコードで回答します。
配列list の元になる、ソート対象の配列は、ご質問に挙げられているコードでは

javascript

1var list = testSort([["aaa",10],["bbb",20],["ccc",""],["ddd",30],["eee",40]]);

javascript

1var list = testSort([["aaa",100],["bbb",10],["ccc",""],["ddd",30],["eee",40]]);

となっていますが、上記のように各要素である長さ2の配列の2番目の要素が、空文字列以外は正の数であるということを前提にしてよいのであれば、sortに与える比較関数は、冒頭の**(1)(2) **を両方使って、以下で事足ります。

javascript

1function(a, b){ 2 return b[1] - a[1]; 3}

上記は、アロー関数を使えば以下のようにも書けます。

javascript

1(a, b) => b[1] - a[1]

ソート対象の配列において、各要素の配列の2番目の値が0および負の数も含むことがあり、その場合も空文字列を含む配列は最後になるようにソートしたいのであれば、 b[1] - a[1] を返す前に、いずれかが空文字列だった場合の if 文を追加して、以下のようにします。この場合は、冒頭の**(2) **のみを使うということになります。

javascript

1function(a, b){ 2 if (a[1] === "") return 1; 3 if (b[1] === "") return -1; 4 return b[1] - a[1]; 5}

上記は、アロー関数と入れ子の三項演算子を使って、以下のようにも書けます。

javascript

1(a, b) => a[1] === "" ? 1 : (b[1] === "" ? -1 : b[1] - a[1])

ただし、上記のコードのように三項演算子を入れ子にするのは、(ESLintにこれを警告させるように設定できるように、)読みにくいコードになりがちなので、業務では使わないほうがよいかもしれません。

投稿2020/02/21 02:49

編集2020/02/22 02:25
jun68ykt

総合スコア9058

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

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

NyankoTaisa

2020/02/21 11:11

function(a, b){ if (a[1] === "") return 1; if (b[1] === "") return -1; return b[1] - a[1]; } データに0を含む場合もありますので、上記を参考に実装し、期待動作を確認できました。 ご回答ありがとうございました!助かりました。
jun68ykt

2020/02/21 14:02

どういたしまして > 期待動作を確認できました。 とのことでよかったです ????
guest

0

javascript

1const callback=(x,y)=>x[1]==y[1]?0:x[1]<y[1]; 2var list = [["aaa",100],["bbb",10],["ccc",""],["ddd",30],["eee",40]]; 3console.dir(list.sort(callback));

投稿2020/02/20 09:21

編集2020/02/20 09:25
yambejp

総合スコア116724

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

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

yambejp

2020/02/20 09:31

数字の空を""でするのはどうかと・・・0ないしマイナスの数値ではだめなのでしょうか?
NyankoTaisa

2020/02/21 11:14

csvから取得したデータを配列にするので、基本は数字ですが、まれに""が入ってしまう場合があり、その場合を考慮した実装にしたかった次第です。 ご回答ありがとうございます。こんなにスッキリとしたコードが書けるとは思っていなかったです。 参考にいたします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問