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

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

ただいまの
回答率

87.34%

配列の数字から一番近い数を表示させたい

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 1,436

score 15

最近プログラミングを始めまして、次にくる電車の時刻を出せるwebサイトを作りたいと思ってるんですど、配列に時刻を入れてからどうすればいいのかわかりません、アドバイスをもらえないでしょうか?

let now = new Date();
let hour = now.getHours();
let mini = now.getMinutes();


const time = [
    509,
    519,
    529,
    539,
    549,
    559,
    609,
    615,
    621,
    624,
    628,
    632,
    636,
    639,
    642,
    645,
    649,
    653,
    656,
    659,
    701,
    704,
    707,
    709,
    711,
    714,
    717,
    720,
    723,
    726,
    728,
    730,
    733,
    735,
    737,
    739,
    742,
    744,
    746,
    748,
    751,
    753,
    755,
    757,
    800,
    802,
    804,
    806,
    809,
    811,
    813,
    815,
    818,
    820,
    822,
    824,
    827,
    829,
    831,
    833,
    836,
    839,
    841,
    844,
    844,
    844,
    847,
    850,
    853,
    857,
    900,
    903,
    906,
    908,
    912,
    915,
    918,
    921,
    925,
    929,
    932,
    936,
    940,
    944,
    948,
    952,
    956,
    1000,
    1004,
    1008,
    1012,
    1016,
    1020,
    1024,
    1028,
    1032,
    1036,
    1040,
    1044,
    1048,
    1052,
    1056,
    1100,
    1104,
    1108,
    1112,
    1116,
    1120,
    1124,
    1128,
    1132,
    1136,
    1140,
    1144,
    1148,
    1152,
    1156,
    1200,
    1204,
    1208,
    1212,
    1216,
    1220,
    1224,
    1228,
    1232,
    1236,
    1240,
    1244,
    1248,
    1252,
    1256,
    1300,
    1304,
    1308,
    1312,
    1216,
    1320,
    1324,
    1328,
    1332,
    1336,
    1340,
    1344,
    1448,
    1352,
    1556,
    1400,
    1404,
    1408,
    1412,
    1416,
    1420,
    1424,
    1428,
    1432,
    1436,
    1440,
    1444,
    1448,
    1452,
    1456,
    1500,
    1504,
    1508,
    1512,
    1516,
    1520,
    1524,
    1528,
    1532,
    1536,
    1540,
    1544,
    1548,
    1552,
    1556,
    1600,
    1604,
    1608,
    1612,
    1616,
    1620,
    1624,
    1627,
    1630,
    1632,
    1635,
    1637,
    1640,
    1642,
    1645,
    1648,
    1650,
    1653,
    1656,
    1700,
    1703,
    1706,
    1708,
    1711,
    1714,
    1717,
    1719,
    1722,
    1724,
    1727,
    1729,
    1732,
    1734,
    1739,
    1742,
    1744,
    1747,
    1749,
    1752,
    1754,
    1757,
    1759,
    1802,
    1804,
    1807,
    1809,
    1812,
    1815,
    1818,
    1820,
    1823,
    1825,
    1828,
    1830,
    1833,
    1835,
    1838,
    1840,
    1843,
    1845,
    1848,
    1851,
    1854,
    1856,
    1858,
    1901,
    1904,
    1908,
    1911,
    1914,
    1918,
    1921,
    1924,
    1927,
    1931,
    1935,
    1939,
    1942,
    1945,
    1953,
    1956,
    2000,
    2004,
    2008,
    2011,
    2014,
    2018,
    2021,
    2024,
    2028,
    2031,
    2035,
    2040,
    2043,
    2047,
    2051,
    2054,
    2058,
    2101,
    2104,
    2104,
    2109,
    2114,
    2119,
    2124,
    2129,
    2134,
    2139,
    2144,
    2149,
    2154,
    2159,
    2204,
    2209,
    2214,
    2219,
    2224,
    2229,
    2234,
    2239,
    2244,
    2249,
    2254,
    2259,
    2304,
    2309,
    2313,
    2319,
    2324,
    2328,
    2332,
    2339,
    2345,
    2356,
];
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2019/09/10 11:22

    「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを、出ているエラーなどと併せて、具体的に記述されたほうが回答を得られやすいと思います。

    キャンセル

  • what

    2019/09/10 13:53

    ご指摘ありがとうございます。
    コードのどの部分で詰まってるというか、どのようにしてfor文を作ったりしたらいいのかというのが考えるのが苦手です。そういう考えを身につけるにはどのようなことをすればいいでしょうか?
    長文で申し訳ありません。

    キャンセル

回答 5

+2

途中に

1448,
1352,
1556,

というデータが入って順列なデータになっていません
そのあたりの整理が必要です。(今のままだとソートや重複削除が必要)
またできればフォーマットをあわせて"0509"みたいなデータにしたほうがやりやすいでしょう。

sample

配列が時間順に並んでいるなら次の電車はこんな感じです

var now = new Date();
var hour = (100+now.getHours()).toString().substr(-2);
var min = (100+now.getMinutes()).toString().substr(-2);
var hm=hour+min;
const times = [
"0509","0519","0529","0539","0549","0559",
"0609","0615","0621","0624","0628","0632","0636","0639","0642","0645","0649","0653","0656","0659",
"0701","0704","0707","0709","0711","0714","0717","0720","0723","0726","0728","0730","0733","0735","0737","0739","0742","0744","0746","0748","0751","0753","0755","0757",
"0800","0802","0804","0806","0809","0811","0813","0815","0818","0820","0822","0824","0827","0829","0831","0833","0836","0839","0841","0844","0844","0844","0847","0850","0853","0857",
"0900","0903","0906","0908","0912","0915","0918","0921","0925","0929","0932","0936","0940","0944","0948","0952","0956",
"1000","1004","1008","1012","1016","1020","1024","1028","1032","1036","1040","1044","1048","1052","1056",
"1100","1104","1108","1112","1116","1120","1124","1128","1132","1136","1140","1144","1148","1152","1156",
"1200","1204","1208","1212","1216","1220","1224","1228","1232","1236","1240","1244","1248","1252","1256",
"1300","1304","1308","1312","1216","1320","1324","1328","1332","1336","1340","1344",
//"1448","1352","1556",
"1400","1404","1408","1412","1416","1420","1424","1428","1432","1436","1440","1444","1448","1452","1456",
"1500","1504","1508","1512","1516","1520","1524","1528","1532","1536","1540","1544","1548","1552","1556",
"1600","1604","1608","1612","1616","1620","1624","1627","1630","1632","1635","1637","1640","1642","1645","1648","1650","1653","1656",
"1700","1703","1706","1708","1711","1714","1717","1719","1722","1724","1727","1729","1732","1734","1739","1742","1744","1747","1749","1752","1754","1757","1759",
"1802","1804","1807","1809","1812","1815","1818","1820","1823","1825","1828","1830","1833","1835","1838","1840","1843","1845","1848","1851","1854","1856","1858",
"1901","1904","1908","1911","1914","1918","1921","1924","1927","1931","1935","1939","1942","1945","1953","1956",
"2000","2004","2008","2011","2014","2018","2021","2024","2028","2031","2035","2040","2043","2047","2051","2054","2058",
"2101","2104","2104","2109","2114","2119","2124","2129","2134","2139","2144","2149","2154","2159",
"2204","2209","2214","2219","2224","2229","2234","2239","2244","2249","2254","2259",
"2304","2309","2313","2319","2324","2328","2332","2339","2345","2356",
];

console.log(times.filter(x=>x>hm)[0]||null);


※上記たとえばhmが"2357"だったりしたらnullが返ります
もし24時以降の運行がある場合、現時刻が0時以降になると先頭がとられちゃうので
工夫が必要になります

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/10 14:03

    ご指摘ありがとうございます。配列を手打ちでしていたので、打ち間違えてました。
    また詰まったら助けていただけたら幸いです。

    キャンセル

  • 2019/09/10 14:18

    一応sampleつけておきました

    キャンセル

checkベストアンサー

+1

こんにちは

ご質問に挙げられているコードにある、時刻を整数値で表した要素を昇順に並べた配列 time は修正せずにそのまま使うとします。(※ 一部、昇順になっていない箇所があるので、追記しました。)

現在の時刻が11時45分とすると、以下

let now = new Date();
let hour = now.getHours();
let min = now.getMinutes();


によって hour に 11、 min に 45 が入りますので、これらから 1145 という整数値を作って、何らかの変数、たとえば x に入れます。

次に考えるべき主たる課題は、 以下のような i’ を見つけることです。

x < time[i]  (ただし、 0itime.length )

を満たす i は複数あり得るが、そのうち最小の i を i’ とすれば、 time[i’] が答え

なお上記は、現在時刻が、いずれかの発車時刻と等しくても、その電車には間に合わないので、次の電車に乗るという考え方です。

アドバイスをもらえないでしょうか?

とのことですので、上記のような i’ の探し方を考えるときに参考になる記事を以下に挙げます。

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

追記

ご質問のコードで time の中に、一部、以下

    1344,
    1448,
    1352,
    1556,
    1400,


のように昇順になっていない箇所がありますので、ここは正しく昇順になるように、修正が必要です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/10 14:00

    ご指摘ありがとうございます。実装できるかわかりませんが頑張ってみます。それからアルゴリズムをしっかり学んでみようと思います🙇‍♂️ また詰まったら助けていただけたら幸いです

    キャンセル

  • 2019/09/10 15:40

    どういたしまして。コメントありがとうございます。

    > 実装できるかわかりませんが頑張ってみます。

    はい。それはとても良いチャレンジですね。

    このご質問に挙げられている、WEB時刻表を作るということだけに目的を限れば、time のどの要素とどの要素との間に現在時刻が該当するのかを見つけるために、わざわざ自分で二分探索を書くことはなく、 先頭から順々に比較していっても、実用上、ほとんど差はないと思われますが、
    > 最近プログラミングを始めまして、
    とのことでしたので、このご質問を土台にして、ご自身で二分探索を書いてみて、先頭から順々に比較していった場合と比べて、該当する timeの要素をみつけるまでに、現在時刻とtimeの要素との大小比較の回数や解にたどりつくまでの時間にどのくらい差が出るかを、(time の要素数を10倍、100倍、 1000倍、、、と、増やしてみたりもしつつ、)比べてみたりすると、アルゴリズム学習の手頃なきっかけになるかと思います。

    キャンセル

+1

現在の時間以後で、かつ、一番近い時刻を探せばいいということになりますね

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/10 14:02

    ありがとうございます。考え方は理解できそうです。
    他の回答者さんの記事も参考にしながら作ってみようと思います。
    またコーディングに詰まったら助けていただけたら幸いです。

    キャンセル

+1

1, きちんと並べる。
2, フォーマットをXXXXのように4桁にする。
3, forで1ずつ足す。

3に関しては色々例外処理が必要なので別で質問を立てることをお勧めします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/10 14:00

    ご指摘ありがとうございます。フォーマットを4桁にするという発想はなかったです(⌒-⌒; )。
    恥ずかしながらfor文も作ることが苦手ですけど、試行錯誤して頑張ってみます。
    また詰まったら助けていただけたら幸いです。

    キャンセル

0

配列は昇順に直してください。

二分探索は高速ですが、この程度のデータであれば線形探索で十分だと思います。

Array.prototype.find()

しかし、この質問の仕様では、日をまたいだ探索ができません。そこで、次の日の始発の時間に 24 を加えたものを配列の最後に追加します。
例えばそれが 0 時 25 分だった場合、2425 を加えるということです。

Array.prototype.push()

そうすれば、必ず現在時刻以降のデータが存在することが保証されるので、効率よく探索できます。この手法を番兵といいます。

番兵

追記

低評価した人は理由を書きなさい。

追記

日本語が読めないのか?
理由を書け。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/10 14:04

    ご指摘ありがとうございます。昇順間違えは手打ちでしていたので気づかなかったです。
    二分探索というのを始めて知りました。知識提供ありがとうございます。
    色々な記事を参考にしながら頑張ってみます
    また詰まったら助けていただけたら幸いです

    キャンセル

  • 2019/09/10 14:08

    私が勧めているのは線形探索で、いろいろな記事を参考にしなくてもリンク先に数字を変えればいいだけのサンプルがありますが。

    キャンセル

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

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る