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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

JavaScript

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

3600閲覧

javascript 複数のオブジェクトを取得したい

tenten11055

総合スコア67

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

JavaScript

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/01/21 09:35

#やりたいこと
下の画像のように、プルダウン選択が二つある場合、
一つ目で選んだ項目を二つ目の選択肢から消したい。
イメージ説明

#例えば・・
industriesというオブジェクトがあって、表示は日本語,選択時のvalueはkeyのidとなる
industries = {1: スポーツ, 2: メディア, 3: 建設}

1つ目のプルダウンで 1:スポーツ を検索すると

2つ目のプルダウンでは {2: メディア, 3: 建設} のみ選択肢に現れるようにしたい。

#やってみたこと
filterメソッドを駆使してみたものの、配列じゃないと使えない。

1つ目に選択したidを引数に、下記のメソッド発火
this.industriesには {1: スポーツ, 2: メディア, 3: 建設} が入っているとしてください。

js

1 fetch_sub_industries(industry_id) { 2 if(industry_id) { 3 this.sub_industries = Object.keys(this.industries).filter(function (sub_industry_id) { 4 return sub_industry_id !== industry_id 5 }) 6 console.log(this.sub_industries) 7 } 8 },

結果は [2, 3] となるが、ここから {2: メディア, 3: 建設} というような検索も難しい。。
どなたかご教示いただけると助かります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは

ご質問に挙げられているコードの意図に沿って、関数 fetch_sub_industries は、 this.industries を新しいオブジェクトで書き換えるものとします。この前提で、filterを使うのであれば、以下のようにすればよいかと思います。

javascript

1function fetch_sub_industries(industry_id) { 2 let entries = Object.entries(this.industries); 3 entries = entries.filter(([id]) => +id !== industry_id); 4 this.industries = Object.fromEntries(entries); 5}

追記

配列やオブジェクトの操作で便利なライブラリ lodash の _.omit を使うと、以下のように手短かに書けます。

javascript

1function fetch_sub_industries(industry_id) { 2 this.industries = _.omit(this.industries, industry_id); 3}

追記2

新しいオブジェクトを作って、this.industries に再度代入するのではなく、現状の this.industries から、単に industry_id で指定されるプロパティを除去すればよいのであれば、以下でもよいかと思います。

javascript

1function fetch_sub_industries(industry_id) { 2 delete this.industries[industry_id]; 3}

追記3

上記の回答は、ご質問にある関数 fetch_sub_industries を、ご質問にある意図通りにするための修正案ですが、2つの<select> を連動させて、1つ目の seelct で選ばれた選択肢を、2つ目の select では表示させないようにすることが主目的なのであれば、2つのselectは両方とも常にoptionを3つ持つようにしておき、1つ目で選ばれた選択肢を2つ目で非表示にするために、CSSの displaynone にするという手もあるかと思います。

以下、そのサンプルです。

追記4

コメントから頂きました

ソースをみて不明な点があり、

について回答します。

まず、

MDNの JavaScript のデータ型とデータ構造 の中にある、Object のセクションのプロパティの説明に、以下のように書かれています。

キー値は String 値または Symbol 値です。

これを確かめるために、

javascript

1this.industries = { 1: "スポーツ", 2: "メディア", 3: "建設" }; 2 3console.log(Object.keys(this.industries));

とすると、以下で確認できるように、 [ 1, 2, 3 ] ではなく、 ["1", "2", "3"] と表示されます。

すなわち、this.industries のプロパティのキーは、 1,2,3 という整数値ではなく、文字列の "1" , "2", "3" として保持されています。

同様に、一番初めに挙げた回答コード

にある、以下の行

javascript

1let entries = Object.entries(this.industries);

で得られる entries を console.log で表示すると、以下のようになり、エントリーのキーは、"1", "2", "3" と、文字列として取得されてくることが確認できると思います。

[["1", "スポーツ"], ["2", "メディア"], ["3", "建設"]]

上記の配列 entries を filter でループさせるときに、filter の引数として与える関数には、上記の
["1", "スポーツ"]
という形、すなわち長さが2で先頭要素が元のオブジェクトのプロパティのキー(文字列です)、二番目の要素がプロパティの値である配列が引数として渡されてくるので、以下のようにすれば、key, value という変数名で、この配列の要素を受け取れます。(以下のコードで [key, value] という書き方は分割代入と呼ばれ、追記5 に説明しました。)

javascript

1entries.filter(([key, value]) => { 2 // 何らかの判定ロジック 3 retrurn trueまたはfalse 4})

function fetch_sub_industries(industry_id) では、プロパティのキーが、industry_id と等しいかだけを見ればよいので、value は不要で、keyのほうは id と呼ばれる値なので

javascript

1entries.filter(([id]) => { 2 // 何らかの判定ロジック 3 retrurn trueまたはfalse 4})

と書いて、idという変数名で ["1", "スポーツ"]"1" を受け取ります。
次に、// 何らかの判定ロジック の部分を書いて、その結果を反映して true かfalse を返すようにします。
idfunction fetch_sub_industries に渡される industry_id に等しくない場合にのみ、filter によって残されればよいので、

javascript

1entries.filter(([id]) => { 2 return id !== industry_id 3})

と書けばよさそうですが、これだと、うまくいきません。
なぜなら、関数fetch_sub_industries の引数 industry_id のほうは文字列ではなく、たとえば 1 だったりの整数が渡され、他方、

javascript

1entries.filter(([id]) => { 2 return id !== industry_id 3})

と書いた場合の filter のループで呼ばれる関数の引数(の配列要素の) id には "1" だったりの文字列が渡されてくるため、

id !== industry_id

は(両辺の型が違うので、値を比較するまでもなく、)必ずtrueになります。したがって fetch_sub_industries(1) としたときも ["1", "スポーツ"] が除外されず、結果としてthis.industries は元のオブジェクトの3つのエントリ(キーと値の組)をどれも持つものとなってしまいます。以下で確認できます。

!== によって意図した判定が行われるには、両辺の型を揃える必要がありますが、回答のコードでは、関数fetch_sub_industries の引数industry_idは整数値が渡されることを前提として、両辺を数値にあわせることにしました。そのためには filter のループで使われる id のほうを文字列から数値に変換しなければなりません。数字の文字列である id を数値に変換する方法としては、Number(id)parseInt(id) (より厳密には、parseInt(id, 10) ) とすればよいですが、もっと簡単に書く方法として

+id

と書くことでも数値が得られます。 これにより、id がたとえば "1" ならば、数値の 1 が得られます。このような + は単項加算(unary plus)と呼ばれます。以下は MDN の単項加算の説明です。

単項加算を使って、!== の両辺を数値にあわせて、

javascript

1entries.filter(([id]) => { 2 return +id !== industry_id 3})

とすれば、意図通りに filter が機能します。さらに、アロー関数の本体が1行であり return で値を返しているので、上記を詰めて、

javascript

1entries.filter(([id]) => +id !== industry_id)

と書いたものが、回答に挙げたコードになります。

ちなみに、もし、id の型に合わせて、文字列の比較にするならば、industry_id のほうを文字列にする必要があるので、たとえば

javascript

1entries.filter(([id]) => id !== `${industry_id}`)

のようにします。

上記のように、厳密な比較の !== を使うと、数値か文字列のいずれかに型を合わせる必要がありますが、これがやや煩雑と思えば、厳密でない比較の != を使って

javascript

1id != industry_id

と書くことで、文字列である id のほうが、数値(Number型)に変換されてから、その値が、industry_id と等しくないかを判定します。!==!= の違い(あるいは ===== の違い)を確認するには、以下に説明があります。

上記のような場合、 idindustry_id とで、いずれかの型を他方に、(たとえば上記のように id に単項加算を追加して、)明示的に合わせて ===!== で比較したほうがよいのか、あるいは ==!= を使って、型を明示的に合わせることを不要にして比較するほうがよいのかについては、「時と場合による」という考え方もできますが、ひとつのガイドとして、javascript のコードチェックツールの ESLint の様々なルールの中に

  • == および != は使わないようにして、 === および !== を使うべき

という、以下のルール

It is considered good practice to use the type-safe equality operators === and !== instead of their regular counterparts == and !=.

があります。ですので、(私もそうですが)ふだん ESLint を効かせながらコードを書いていると、 != を使った
id != industry_id
というコードを書くとESLintに警告されるので、型を合わせて === および !== を使うほうに慣れてきます。(実際私は、ここ数年、業務では == および != をほとんど使ってないです。)

追記5

もう一点、

this.industriesが

[[1: "スポーツ"], [2: "メディア"], [3: "建設"]]
のようになっていて、
.filter(([id]) =>
で1,2,3が回るようになる?とすれば、なぜこれで1,2,3が回るのか。

についてですが、2つの要素を持つ配列 ["1", "スポーツ"] を引数にとる関数を書くときに、この配列を aryという引数で受けて、

javascript

1const f = (ary) => { 2 const id = ary[0];  // "1" 3 const name = ary[1]; // "スポーツ" 4 ・・・ 5} 6 7f(["1", "スポーツ"]); 8

と書くこともできますが、引数の ary[id, name] として

javascript

1const f = ([id, name]) => { 2 console.log(id); //=> "1" 3 console.log(name); //=> "スポーツ" 4 ・・・ 5} 6 7f(["1", "スポーツ"]);

と書くことで、idname に直接、配列の先頭と2番目の要素が得られます。これは、配列の分割代入を、関数の引数に使った書き方です。分割代入については以下に説明されています。

また、MDNのObject.entriesの説明 の冒頭にも、以下のようなサンプルがあります。

javascript

1const object1 = { 2 a: 'somestring', 3 b: 42 4}; 5 6for (let [key, value] of Object.entries(object1)) { 7 console.log(`${key}: ${value}`); 8}

上記では、、Object.entries で得られる配列の要素を for ・・・ ofのループで得るときに、・・・ の部分を[key, value] と書くことで分割代入を使い、キーと値を得ています。

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

投稿2020/01/21 12:34

編集2020/01/22 01:46
jun68ykt

総合スコア9058

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

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

tenten11055

2020/01/21 16:19

CodePenまでありがとうございます!! 感動しました!
tenten11055

2020/01/21 16:45

ソースをみて不明な点があり、お手数なのですが、 こちら↓の、 entries = entries.filter(([id]) => +id !== industry_id); この部分↓について、どういう動きになっているのか教えていただけないでしょうか。。 ([id]) => +id  this.industriesが [[1: "スポーツ"], [2: "メディア"], [3: "建設"]] のようになっていて、 .filter(([id]) => で1,2,3が回るようになる?とすれば、なぜこれで1,2,3が回るのか。 また、 +id がどのような働きをしているのか。
jun68ykt

2020/01/21 23:05

どういたしまして > 感動しました! とのことでよかったです???? > ソースをみて不明な点があり、 との件について、回答のほうに、追記4として返答しました。参考になれば幸いです。
jun68ykt

2020/01/21 23:34

分割代入について、回答に追記5を記載しました。
tenten11055

2020/01/22 01:01

大変わかりやすかったです! 勉強になりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問