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

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

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

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

Q&A

解決済

2回答

1224閲覧

JavaScriptにて配列内の特定の文字を取り出し、配列の一番後ろに移動させたい

snafkin999

総合スコア27

JavaScript

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

1グッド

0クリップ

投稿2022/10/25 16:06

前提

JavaScriptを使用して配列の並びを変えたい

実現したいこと

配列内の特定の文字列を取得し、配列の一番後ろに移動させたい
push()やfillter()を使用して並び替えようとしたけど上手くいかない。
もっとスマートな書き方があれば教えてほしいです。

発生している問題・エラーメッセージ

filterとpushで構文を書いても思った通りに出力されない

該当のソースコード

JavaScript

1const items = ['ああ','あい','さく','とり']; 2// 'あい'だけを取り出した変数を作成 3const aaa = items.filter((e)=>{return e === 'あい'}); 4// 'あい'以外を取り出した配列を作成 5const result = items.filter((v)=>{return v !== 'あい'}); 6// ’あい’のない配列の末尾に'あい'を追加する 7const ddd = result.push(aaa); 8console.log('result',ddd); // 4と表示される。。。なぜ???? 9 10// ↓こうなってほしかった 11['ああ','さく','とり','あい']
Cocode👍を押しています

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

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

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

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

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

guest

回答2

0

不具合の理由

  • items.filter()は、配列itemsを元にして新しい配列を生成しますので、const aaa = items.filter(...)のように、定数・変数の中に格納するのが正解です。
  • 対してresult.push()は、配列resultに直接変更を加える形で追加します。新しい配列を生成するわけではないので、定数・変数に格納すると意図しない結果となります。
    • result.push(aaa)をしたら、変数に格納せず、
    • そのまま、console.log(result)と確認をしましょう。
  • また、定数aaaは長さが1の['あい']という配列です。このままプッシュすると、['ああ', 'さく', 'とり', ['あい']]という結果になってしまいます。

不具合確認用コード

こちらは不正解のコードです。質問者様の書いたコードがどのような処理になっているのか、一つ一つconsole.logで表示させて確認してみましょう。

javascript

1const items = ['ああ','あい','さく','とり']; 2 3// 'あい'だけを取り出した変数を作成 4const aaa = items.filter((e)=>{return e === 'あい'}); 5console.log('aaa', aaa); // ['あい',] 6 7// 'あい'以外を取り出した配列を作成 8const result = items.filter((v)=>{return v !== 'あい'}); 9console.log('result', result); //  ['ああ', 'さく', 'とり'] 10 11// ’あい’のない配列の末尾に'あい'を追加する 12result.push(aaa); 13console.log('result', result); // ['ああ', 'さく', 'とり', ['あい']]

おすすめの方法

質問者様のおっしゃっている通り、とても回りくどい処理をしています。
ですのでもう少し簡潔なコードにしてみました。

.splice()メソッドで要素を取り出す

.splice()で任意の要素を取り出すといいでしょう。
元の配列に直接変更を加えるタイプのメソッドです。
さらに、変数に格納することで取り出した値が格納された配列を取得することができます。

javascript

1配列.splice(<取り出す要素のインデックス番号>, <何個取り出すかの数>) 2 3// 例 4const arr = ['a', 'b', 'c', 'd']; 5const c = arr.splice(2, 1); 6console.log(c); // ['c']; 7console.log(arr); // ['a', 'b', 'd']
.indexOf()メソッドでインデックス番号を調べる

.splice()を使うために'あい'のインデックス番号を知らなければなりません。
インデックス番号は、.indexOf()で調べられます。

javascript

1配列.indexOf(<検索する値>) 2 3// 例 4const arr = ['a', 'b', 'c', 'd']; 5const index = arr.indexOf('b'); 6console.log(index); // 1

以上2つのメソッドを組み合わせて使用した上で、元の配列itemsに取り出した'あい'.push()してやるといいでしょう。

正解コード例

javascript

1const items = ['ああ','あい','さく','とり']; 2 3const [ai] = items.splice(items.indexOf('あい'), 1); // 分割代入 4console.log('ai', ai); // 'あい' 5console.log('items', items); // ['ああ', 'さく', 'とり'] 6 7items.push(ai); 8console.log('items', items); // ['ああ', 'さく', 'とり', 'あい']

投稿2022/10/25 16:46

Cocode

総合スコア2314

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

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

Cocode

2022/10/25 16:48

BA決定後に失礼しました。書くのが遅すぎました><!
snafkin999

2022/10/25 16:49

ご回答ありがとうございます。 おすすめや回答例まで丁寧に感謝します! 大変勉強になりました!
guest

0

ベストアンサー

スマートな書き方の直接的な回答ではなく、なぜ質問のコードでは期待通りの結果にならないかについてですが、
push の戻り値は、要素を追加した後の配列ではなく、メソッドが呼び出されたオブジェクトの新しい length プロパティです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/push

result.push(aaa);
の段階で result の要素の個数は 4個になるので、戻り値は 4 になります。
結果、元のコードでは ddd に 4 が入っています。
要素は result の方に追加されているので、ddd のように戻り値を受ける必要はなく result をそのまま使えばよいです。

ただし、aaaは配列(['あい'])なので、スプレッド構文を使う等して配列をばらす必要があります。

js

1const items = ['ああ','あい','さく','とり']; 2// 'あい'だけを取り出した変数を作成 3const aaa = items.filter((e)=>{return e === 'あい'}); 4// 'あい'以外を取り出した配列を作成 5const result = items.filter((v)=>{return v !== 'あい'}); 6// ’あい’のない配列の末尾に'あい'を追加する 7result.push(...aaa); 8console.log('result', result);

短くするなら下記のようになるでしょうか。

js

1const items = ['ああ','あい','さく','とり']; 2const target = 'あい'; 3const result = items.includes(target) ? [...items.filter(v => v !== target),target] : items; 4 5console.log(result);

または、

js

12const result2 = [...items.filter(v => v !== target), ...items.filter(v => v === target)]; 3 4console.log(result2)

投稿2022/10/25 16:21

編集2022/10/25 16:44
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

snafkin999

2022/10/25 16:50

なぜ上手くいかないかの説明まで 丁寧に回答いただきありがとうございました。 とても勉強になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問