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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

2689閲覧

ruby 配列で数字を+1ずつ増やしたい

pokerStars

総合スコア67

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2018/10/23 07:50

編集2018/10/24 01:33
vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[n]) @vod1 = vod1.map{|a| a.attribute('alt')}

vod1の最後のnの部分を+1ずつ増えるようにしたいのですが、どのように書けばいいのでしょうか?

view

1 <% if @arrays.present? %> 2<% @arrays.each do |array| %> 3 <br> 4 <div><%= array["title"] %></div> 5 <br> 6 <div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path"] %></div>      7 <br> 8 <div><%= array["overview"] %></div> 9 <br> 10 <div><%= array["release_date"] %></div> 11 12 13 <% if @vods.present? %> 14 15  <p><%= @vod1 %></p> 16  <% if @vod2.present? %> 17  <p><%= @vod2 %></p> 18  <% end %> 19  <% if @vod3.present? %> 20  <p><%= @vod3 %></p> 21  <% end %> 22  <% if @vod4.present? %> 23  <p><%= @vod4 %></p> 24  <% end %> 25   26   27 <% end %> 28 29 30<% end %>

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

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

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

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

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

guest

回答1

0

Ruby

1n = 10 2(1..n).each { |i| 3 vod1 = ....div[i]) 4}

こういうことですかね。

投稿2018/10/24 02:10

dice142

総合スコア5158

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

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

pokerStars

2018/10/24 03:50 編集

controller n = 10 (1..n).each { |i| vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img') vod2 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[2]/div/a/div/img') vod3 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[3]/div/a/div/img') vod4 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[i]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[4]/div/a/div/img') } doc = Nokogiri::HTML.parse(driver.execute_script('return document.documentElement.innerHTML')) # 検索結果のタイトルを表示 doc.xpath('/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]').each do |node| @vod1 = vod1.map{|a| a.attribute('alt')} @vod2 = vod2.map{|a| a.attribute('alt')} @vod3 = vod3.map{|a| a.attribute('alt')} @vod4 = vod4.map{|a| a.attribute('alt')} このようにしてみたのですが、undefined local variable or method `vod1' こういったエラーになってしまうのですが、書き方がおかしいのでしょうか?
dice142

2018/10/24 03:36

vod1がeach内でしか使えない変数になっているのだと思います。 どういう使い方をしたいのかわからないのですが、ループ内で完結させるかviewにわたすなら@vod1などを配列にするのが良いかと。
pokerStars

2018/10/24 03:49

上記のコードは全てcontrollerでの記述で、div[i]の数字を変えて view <% if @arrays.present? %> <% @arrays.each do |array| %> <br> <div><%= array["title"] %></div> <br> <div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path"] %></div>      <br> <div><%= array["overview"] %></div> <br> <div><%= array["release_date"] %></div> <% if @vods.present? %>   <p><%= @vod1 %></p>   <% if @vod2.present? %>   <p><%= @vod2 %></p>   <% end %>   <% if @vod3.present? %>   <p><%= @vod3 %></p>   <% end %>   <% if @vod4.present? %>   <p><%= @vod4 %></p>   <% end %>      <% else %>   <p>配信しているvodはありません!!</p> <% end %> <% end %> <% end %> 表示する情報を変えたいと思っています。
pokerStars

2018/10/24 03:50

viewは上記の記述です
pokerStars

2018/10/24 03:58 編集

元は、 vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img') としていてdiv[1]しか取得できないので数字を配列ごとにdiv[2],div[3]と変えたいと思っています。
dice142

2018/10/24 03:57

配列ではなく、同じ変数を使っている限りview側で表示を変えることはできないと思うのですが。 controller側でループで数値を変えても、同じ変数に入れてる限りは最後の値しか格納されません。 view側を見る限りループさせているわけでもなさそうですし、どう表示したいのかがいまいち伝わってないです。
pokerStars

2018/10/24 04:08

理想の表示は、作品ごとにみれるvodが違うので表示を変えたいのですが、 例. 現在 検索名「ゴジラ」 作品名「ゴジラ」 vod[amazonプライム]   作品名「ゴジラ2」 vod[amazonプライム]   作品名「ゴジラ3」 vod[amazonプライム]   理想 作品名「ゴジラ」 vod[amazonプライム]   作品名「ゴジラ2」 vod[hulu]   作品名「ゴジラ3」 vod[Netflix]   こういう風にしたいのですが、全部amazonプライムになってしまうという状態です。
pokerStars

2018/10/24 04:18 編集

そのためにdivの数字を1ずつ足していけば解決するのですが、どのようにすればいいかわからないという感じです
dice142

2018/10/24 04:18

作品名とvodとやらはviewにある@array毎に違うということですよね? なのにcontroller側で@vod1などのように設定したら@arrayに関係ないのは当然ではないでしょうか? やるのであれば@arrayのように配列で同じ順で格納するとか@arrayの各要素に追加するとかになります。
pokerStars

2018/10/24 04:32

そうですね! @vod1がおかしいのでしょうか? @vod1はseleniumで指定したxpathのalt属性を表示するという処理を入れているのですが、いまいちどうすればいいかわかりません。 view をいじるのでしょうか?
dice142

2018/10/24 04:38

配列が | A | B | C | D | と4作品分あるとして、 vod1は | X | と1つ分しか格納できないので、いくらcontroller側で void1 = ...div[i]... としても1作品分しか格納できません。 A作品のvod、B作品のvod...というようにしたいのなら vod1も | X | Y | Z | W | のように配列で格納するか 元のarrayに | A,X | B,Y | C,Z | D,W | のようにしないとダメです。
pokerStars

2018/10/24 05:38 編集

controller def index require 'uri' require 'net/http' require 'json' @name = params[:name] a = URI.encode("https://api.themoviedb.org/3/search/movie?api_key=!!&language=ja&query="+@name.to_s) url =URI(a) http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Get.new(url) request.body = "{}" response = http.request(request) hash= JSON.parse(response.body) @arrays = hash["results"] require 'selenium-webdriver' require 'nokogiri' options = Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') options.add_argument('--disable-gpu') driver = Selenium::WebDriver.for :chrome, options: options driver.navigate.to 'https://www.justwatch.com/jp/検索?q=' +@name.to_s wait = Selenium::WebDriver::Wait.new(timeout: 300) wait.until { driver.find_element(xpath: '//div[2]/filter-bar/div[2]/div[2]/div[3]/div[2]/div',) } vod1 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[1]/div/a/div/img') vod2 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[2]/div/a/div/img') vod3 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[3]/div/a/div/img') vod4 = driver.find_elements(:xpath, '/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]/div[4]/div/a/div/img') doc = Nokogiri::HTML.parse(driver.execute_script('return document.documentElement.innerHTML')) # 検索結果のタイトルを表示 doc.xpath('/html/body/div[2]/filter-bar/ng-transclude/core-list/div/div/div[1]/search-result-entry/div/div[2]/div[2]/div/div[1]/div/div/div/div/div[2]/div[1]/div[2]').each do |node| @vod1 = vod1.map{|a| a.attribute('alt')} @vod2 = vod2.map{|a| a.attribute('alt')} @vod3 = vod3.map{|a| a.attribute('alt')} @vod4 = vod4.map{|a| a.attribute('alt')} @vods = [@vod1, @vod2, @vod3, @vod4] end driver.quit end view <p><b>Hulu, U-NEXT,dtv,GYAO!,Amazonprime,Netflixの中から配信中のvodを見つけられます!</b></p> <%= form_tag({action: :index}, {method: :get}) do %> <br> <%= label_tag :name, '作品名' %> <%= text_field_tag :name, @name %> <%= submit_tag '検索', data: { disable_with: '送信中'} %> ※作品名がヒットしない場合、英語入力も試して見てください!! <% end %> <% if @arrays.present? %> <% @arrays.each do |array| %> <br> <div><%= array["title"] %></div> <br> <div><%= image_tag 'https://image.tmdb.org/t/p/w500'+array["poster_path"] %></div>      <br> <div><%= array["overview"] %></div> <br> <div><%= array["release_date"] %></div> <% if @vods.present? %>   <p><%= @vod1 %></p>   <% if @vod2.present? %>   <p><%= @vod2 %></p>   <% end %>   <% if @vod3.present? %>   <p><%= @vod3 %></p>   <% end %>   <% if @vod4.present? %>   <p><%= @vod4 %></p>   <% end %>      <% else %>   <p>配信しているvodはありません!!</p> <% end %> <% end %>
pokerStars

2018/10/24 05:37

全てを表示するとこんな感じなのですが、 aaa = @array.@vod1 こんな感じでまとめるという意味でしょうか?
dice142

2018/10/24 05:42

Rubyの配列や連想配列を復習したほうが良い気がします。
pokerStars

2018/10/24 07:56 編集

配列の復習をしたのですが、@arraysに別の配列を入れ込むことができません @arrays = hash["results"]これと、 vod1 = -div[1]- vod2 =--div[1]- vod3 =--div[1]- vod4 =--div[1]- vods = [vod1,vod2,vod3,vod4] これを繋げて、まとめて出力すればいいということですよね?
pokerStars

2018/10/24 07:57

num = 0 n = num + 1 div[n]みたいにして足していきたいです
dice142

2018/10/24 07:59

@arraysの各要素は連想配列だと思うので、その連想配列に「vod」を追加すると view側でarray['vod']といった感じで出力できるようになります。 もしくは@arraysと同じ順番のvod用配列を用意すれば (0...@arrays.length).each { |i| # @arrays[i]["title"] # @vod_array[i] } で出力できるようになります。
dice142

2018/10/24 08:01

そもそも@arraysと@vod1~@vod4の関係性がわからないので噛み合ってない気もします。
pokerStars

2018/10/24 08:07

@arraysがapiで取得した配列で @vod1はseleniumのスクレイピングで取得したものになります。 ありがとうございます! 一度やってみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問