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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

3回答

1760閲覧

JSONのデータのアクセス方法が知りたい2

www-www

総合スコア12

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/08/23 13:18

編集2018/08/23 13:39

前回からの続きです。
https://teratail.com/questions/142016

引き続き下記のJSONを取得し、作業を行っています。
https://worldcup.sfg.io/matches

やりたいこと

次のステップとして、

  1. home_team_eventsとaway_team_eventsを取得し、2つのteam_eventを結合する
  2. timeを基準にソートし、各チームeventをオブジェクト?に入れる
  3. 連結したオブジェクトを見てタグの出し分けをしたい

ということがしたいです。

やりたいことのイメージ↓

日本vsアルゼンチン
goal 香川6
16goal メッシ
goal 岡崎26
50交代 アグエロ

試したこと

やりたいこと1は、まず配列を連結する必要がると考えcomponentWillMount()内でObject.assign()を行いましたが、エラーになってしまいました。

現在のコード

JSX

1import React, { Component, Fragment } from 'react'; 2import styled from 'styled-components'; 3import axios from 'axios'; 4import User from './App.css' 5 6const MatchItem = styled.div` 7 max-width: 600px; 8 margin: 0 auto 16px; 9 border: 1px solid #ccc; 10`; 11const TeamWrap = styled.div` 12 display: flex; 13`; 14const Team = styled.div` 15 width: 100%; 16 text-align: center; 17 height: 60px; 18 font-weight: bold; 19 display: flex; 20 justify-content: center; 21 align-items: center; 22`; 23const MatchTexts = styled.div` 24 min-width: 50px; 25 flex-shrink: 0; 26 display: flex; 27 font-size: 12px; 28 justify-content: center; 29 align-items: center; 30 border-left: 1px solid #ccc; 31 border-right: 1px solid #ccc; 32`; 33const MatchHeading = styled.div` 34 text-align: center; 35 background: #333; 36 color: #fff; 37 font-weight: bold; 38`; 39 40 41const StatsWrap = styled.div``; 42const GoalWrap = styled.div` 43 display: flex; 44`; 45const Goal = styled.div` 46 width: 100%; 47 text-align: center; 48 height: 30px; 49 font-weight: bold; 50 display: flex; 51 justify-content: center; 52 align-items: center; 53`; 54const EventWrap = styled.div``; 55const EventDetail = styled.div` 56 display: flex; 57 &:not(:last-child) { 58 border-bottom: 1px solid #eee; 59 } 60`; 61const Event = styled.div` 62 width: 100%; 63 text-align: center; 64 height: 30px; 65 display: flex; 66 align-items: center; 67 font-size: 14px; 68`; 69const EventType = styled.div` 70 width: 80px; 71 height: 30px; 72 font-size: 10px; 73 flex-shrink: 0; 74 display: flex; 75 align-items: center; 76 justify-content: center; 77 background: #333; 78 ${({ isGoal }) => isGoal && ` 79 color: #fff; 80 font-weight: bold; 81 } 82 `} 83 ${({ isIn }) => isIn && ` 84 color: #a0d8ff; 85 `} 86 ${({ isOut }) => isOut && ` 87 color: #ffcdcd; 88 `} 89 ${({ isCardY }) => isCardY && ` 90 color: #fffacd; 91 `} 92 ${({ isCardR }) => isCardR && ` 93 color: #ff6363; 94 `} 95`; 96const EventPlayer = styled.div` 97 width: 100%; 98 text-align: center; 99`; 100 101class App extends Component { 102 constructor(){ 103 super(); 104 this.state = { 105 matchDatas:[] 106 }; 107 } 108 componentWillMount(){ 109 const request = axios.create({ 110 baseURL: 'https://worldcup.sfg.io/' 111 }) 112 request.get('/matches') 113 .then(res => { 114 this.setState({ 115 matchDatas: res.data 116 }); 117 }) 118 } 119 render() { 120 return ( 121 <Fragment> 122 {this.state.matchDatas.map((item, index) => ( 123 <MatchItem key={index}> 124 <TeamWrap> 125 <Team>{item.home_team_country}</Team> 126 <MatchTexts>vs</MatchTexts> 127 <Team>{item.away_team_country}</Team> 128 </TeamWrap> 129 <StatsWrap> 130 <MatchHeading>Stats</MatchHeading> 131 <GoalWrap> 132 <Goal>{item.home_team.goals}</Goal> 133 <MatchTexts>Goal</MatchTexts> 134 <Goal>{item.away_team.goals}</Goal> 135 </GoalWrap> 136 </StatsWrap> 137 <EventWrap> 138 <MatchHeading>Events</MatchHeading> 139 {item.home_team_events.map((matchHomeEvent,i) => ( 140 <EventDetail key={i}> 141 <Event> 142 {(() => { 143 if (matchHomeEvent.type_of_event === 'goal') { 144 return ( 145 <EventType isGoal>Goal!!!</EventType> 146 ) 147 } else if (matchHomeEvent.type_of_event === 'goal-penalty') { 148 return ( 149 <EventType isGoal>Goal(PK)</EventType> 150 ) 151 } else if (matchHomeEvent.type_of_event === 'goal-own') { 152 return ( 153 <EventType isGoal>Goal(OWN)</EventType> 154 ) 155 } else if (matchHomeEvent.type_of_event === 'substitution-in') { 156 return ( 157 <EventType isIn>In</EventType> 158 ) 159 } else if (matchHomeEvent.type_of_event === 'substitution-out') { 160 return ( 161 <EventType isOut>Out</EventType> 162 ) 163 } else if (matchHomeEvent.type_of_event === 'yellow-card') { 164 return ( 165 <EventType isCardY>Yellow Card</EventType> 166 ) 167 } else if (matchHomeEvent.type_of_event === 'yellow-card-second') { 168 return ( 169 <EventType isCardR>Yellow Card(2)</EventType> 170 ) 171 } else if (matchHomeEvent.type_of_event === 'red-card') { 172 return ( 173 <EventType isCardR>Red Card</EventType> 174 ) 175 } 176 })()} 177 <EventPlayer>{matchHomeEvent.player}</EventPlayer> 178 </Event> 179 <MatchTexts>{matchHomeEvent.time}</MatchTexts> 180 <Event>aa</Event> 181 </EventDetail> 182 ))} 183 </EventWrap> 184 </MatchItem> 185 ))} 186 </Fragment> 187 ); 188 } 189} 190 191export default App;

まずはやりたいこと1を実現したく、よろしくお願いします。

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

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

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

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

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

guest

回答3

0

目的の機能を見つけるまでの過程

特段難しい事ではありませんが、ちゃんと調べていますか。

  1. home_team_eventsとaway_team_eventsを取得し、2つのteam_eventを結合する

元となるJSONを見れば、

JavaScript

1,"home_team_events":[{"id":5,"type_of_event":"goal","player":"Iury GAZINSKY","time":"12'"},{"id":1,"type_of_event":"substitution-in","player":"Denis CHERYSHEV","time":"24'"},{"id":320,"type_of_event":"substitution-out","player":"Alan DZAGOEV","time":"24'"},{"id":2,"type_of_event":"goal","player":"Denis CHERYSHEV","time":"43'"}, 2... 3,"away_team_events":[{"id":12,"type_of_event":"substitution-in","player":"FAHAD ALMUWALLAD","time":"64'"},{"id":325,"type_of_event":"substitution-out","player":"ABDULLAH OTAYF","time":"64'"},

home_team_eventsaway_team_events が配列である事が分かります。
ならば、後は配列に該当機能があるか調べるだけでしょう。

破壊的/非破壊的の差はありますが、下記機能がある事が分かります。

  1. timeを基準にソートし、各チームeventをオブジェクト?に入れる

それは配列と分かっているので、先と同じように探して、

調べ方

今までの質問履歴を読むと、全てコードを貰って解決しているようですが、まずは調べ方を覚えましょう。
魚から釣り方を覚えられる方ならいいですが、要件だけ書いて「自分で調べたこと」を書かない質問文は「丸投げ」と受け取られがちです。

Re: www-www さん

投稿2018/08/25 11:19

編集2018/08/25 11:24
think49

総合スコア18156

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

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

www-www

2018/08/27 14:43 編集

>要件だけ書いて「自分で調べたこと」を書かない質問文は「丸投げ」と受け取られがちです。 以後気をつけます。 参考ページなどありがとうございました。参考になりました。
guest

0

home_team_eventsとaway_team_eventsというのは配列のようなので、Array.concat で結合できます。

js

1const allEvents = item.home_team_events.concat(item.away_team_events)

投稿2018/08/23 15:38

kakajika

総合スコア3131

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

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

www-www

2018/08/30 12:28

kakajikaさん お返事が遅くなり申し訳ありません。 コメントいただきありがとうございます! 参考にさせていただきます。
guest

0

ベストアンサー

こんにちは。
ご質問に

まずはやりたいこと1を実現したく、よろしくお願いします。

とありましたが、以下の回答には、やりたいこと2と3も含んでいます。その点で、ややお節介の過ぎる回答になってしまっていたらすみません。

www-wwwさんがやりたい3つのことを踏まえて、解法の一例を以下に示します。
(※追記1, 2 に下記コードの修正案を書きました。

javascript

1const timeValue = (timeStr) => { 2 const minutes = timeStr.split("'"); 3 const value = 4 parseInt(minutes[0], 10) + 5 (minutes[1].length > 0 ? parseInt(minutes[1], 10) : 0); 6 7 return value; 8}; 9 10 11const sortedEventsOfBothTeams = (item) => ( 12 ['home_team', 'away_team'] 13   .reduce((ary, team) => { 14   item[`${team}_events`].forEach((event) => { 15    ary.push({ 16 ...event, 17 team, 18 timeValue: timeValue(event.time), 19 }); 20 }); 21 return ary; 22 }, []) 23 .sort((e1, e2) => e1.timeValue - e2.timeValue) 24); 25

上記コードを使って、<table> を作るサンプルを

https://jsfiddle.net/jun68ykt/bw6o1ajx/67/

に試作してみました。これは前回のご質問の回答で作成した https://jsfiddle.net/jun68ykt/bw6o1ajx/7/ を、今回の回答に合わせて修正したものです。

  
上記で作成した2点の関数について、以下、補足説明します。

(1) sortedEventsOfBothTeams(item) が結合された配列を返す関数で、結合した配列を作るときに、以下の2つのプロパティを追加しています。

  1. team --- 文字列"home_team" または "away_team" (後で タグの出し分け のために使う)
  2. timeValue --- timeの文字列を timeValue()で数値に変換した値 (この値の昇順でソートする)

(2) 補助的な関数timeValue() はレスポンスで返される発生時間の文字列、たとえば "55'" を、 数値の55に変換する関数です。アディショナルタイムに入ってからの表記 "90'+3" も数値の 93 に変換されるように作成しています。



※以下の追記1, 2 で上記の2つの関数の修正案を書いてます。


追記1:sortedEventsOfBothTeams の別案

上記のコードでは、 reduce の中に forEachがあって、ちょっと、ぱっと見たときに分かりにくい気がしました。
kakajikaさんのご回答にある、concatを使って、まずは単に結合した配列を作るところから始めるほうがすっきり書けそうです。ソートと出し分け用のプロパティ追加を結合の後で行うことにして、以下のようになりました。

javascript

1const sortedEventsOfBothTeams = (item) => { 2 3 const allEvents = item.home_team_events.concat(item.away_team_events); 4 5 const homeTeamEventIds = item.home_team_events.map(event => event.id); 6 7 return allEvents 8 .map(event => ({ 9 ...event, 10 team: homeTeamEventIds.includes(event.id) ? 'home_team' : 'away_team', 11 timeValue: timeValue(event.time), 12 })) 13 .sort((e1,e2) => e1.timeValue - e2.timeValue); 14};

サンプル: https://jsfiddle.net/jun68ykt/bw6o1ajx/79/


追記2: timeValueの別案

はじめの回答のほうのコードで使った reduce() はいろいろと便利です。たとえば、回答中にある timeValue(timeStr) という関数ですが、reduce() を使ってみると、以下のようにも書けます。

javascript

1const timeValue = timeStr => 2 timeStr.split("'").reduce((total, min) => total + Number(min), 0); 3 4// 以下のように ' で区切られた数値を合計します。 5console.log(timeValue("5'")); // => 5 6console.log(timeValue("77'")); // => 77 7console.log(timeValue("90'+11")); // => 101 8 9console.log(timeValue("10'+11'-5'20'4.5'+0.01")); // => 40.51

投稿2018/08/25 04:26

編集2018/08/26 22:55
jun68ykt

総合スコア9058

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

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

www-www

2018/08/30 12:27

jun68yktさん 前回に続きご回答ありがとうございます!! またお返事が遅くなってしまい申し訳ありません。 jun68yktさんからいただいたコードを理解してから、コメントをしようと思っていたのですが、恥ずかしながらまだ理解できていないところがありまして、遅くなってしまいました。。 まだ理解できていないところがあるのですが、サンプルコードを拝見する限り自分の求めていた挙動となっていましたので、ベストアンサーとさせていただきます。 コードについて不明な点がありましたら、また質問をさせていただければ幸いです。この度はありがとうございました。
jun68ykt

2018/08/31 15:22 編集

www-wwwさん、こんにちは。 とりあえず、 >自分の求めていた挙動となっていました とのことで安心しました。 私も今まさにReactによるSPA開発に関わっていますが、このご質問と同じように、APIから返ってきたJSONを、コンポーネントで使うために望ましい形に加工するロジックを書かなければならない場面に何度も遭遇します。 そのときに、配列の操作をするいくつかの関数、reduce, map, forEach, some, every, filter, sort などを(ときには、これらの2つ以上を組み合わせたりもして、)使いこなせるようになっておくと、仕事をさっさと片づけることができて望ましいわけですが、これらの関数を使いこなせるようになるためにいわゆる「関数型プログラミング」の基礎的な考え方を知っておくと、応用がきくと思います。その考え方の手引きとして、以下の2冊のいずれかをめくってみるとよいかもしれません。 JavaScript関数型プログラミング 複雑性を抑える発想と実践法を学ぶ 出版社: インプレス (2017/6/9) 関数型プログラミングの基礎 JavaScriptを使って学ぶ リックテレコム (2016/10/29) > コードについて不明な点がありましたら、また質問をさせていただければ幸いです。この度はありがとうございました。 どういたしまして。 このご質問のサイトはサッカー情報のサイトでしょうか? 頑張ってください!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問