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

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

ただいまの
回答率

87.35%

java ファイルからのString格納方法

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 400

score 9

java初心者です。

以下のようなテキストがあったとして、これをコロン手前の人間の名前だけを集めた配列と
コロン後ろの複数の人間を集めた二次元配列に分ける場合、どういった方法が簡単でしょうか?

私は以下のようなアプローチをとったのですが、不要なものが多いような気がしたのでお聞きした次第です。

1)ファイルの中身をScannerで取ってきて行数を確認➡配列の数字に利用
2)Scannerで拾ってきた以下中身を「:」もしくは改行でSplit。これをString配列へ格納 ➡ 行数の二倍の数字ができる。
3)奇数は「:」前までの数字、偶数は「:」後の改行までの文字列が入っているので、奇数分をString配列にて格納
4)偶数分については、新たな配列に行ごとに複数のなまえをまるごと格納。
5)1)で行数がわかっているので、二次元配列の前半にその数字を入れて、4)格納した配列から名前をSplitて文字を入れ込む

テキストの中身は以下
Kate: Chris, Joe, Anna, Frank , Nancy
Chris: Kate, Nancy, Peter, Steve, Frank, Tim, Amy
Charles: Sara, Kevin, Peter, Steve
David: Steve, Amy , Bob 
Frank: Anna, Kate, Mary , Pop
Max: Kate , Nancy , Tim
Smith: Kevin, Kate, Tim, Bob

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • BluOxy

    2019/09/22 01:55 編集

    1~5の日本語による説明では動作をイメージするのに限界がありますので、実際のコードを掲示して頂けますか。何をどうするべきかはそのコードをベースに説明できるとより具体的な回答が書けそうです。

    キャンセル

  • KttShK

    2019/09/22 02:11

    以下のように記載しました。 ぐちゃぐちゃな文で恐縮です。

    String[] strBox = listA.toString().split(":|\n");  //こちらで分割 2)に該当
    mainPerson = new String[7];
    for (int i = 0; i < strBox.length/2; i++) {
    mainPerson[i] = strBox[i*2]; // 名前格納
    }
    String[] tempName = new String[strBox.length/2]; お友達を格納

    for (int i = 1; i <= strBox.length/2; i++) {
    tempName[i-1] = strBox[(i*2)-1].toString().replace(" ", "");
    }
    yujin = new String[7][];
    for (int i = 0; i < 7; i++) {
    yujin[i] = tempName[i].trim().split(",");
    }

    キャンセル

  • swordone

    2019/09/22 02:43

    質問を編集してコードを記載してください。

    キャンセル

回答 2

checkベストアンサー

+1

追記修正コメント内のコードを見る限り、行数は決まっているのでしょうか?
だとすれば、あらかじめ配列を人数分作っておき、行ごとに読み込んで順次入れていくという手法が一般的ではないでしょうか。

Scanner s = new Scanner(file); // よくわからんので適当
String[] names = new String[7];
String[][] friends = new String[7][]
for(int i = 0; i < 7; i++) {
    String[] temp = s.nextLine().split(":");
    names[i] = temp[0];
    friends[i] = temp[1].split(",");
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/22 05:25

    ありがとうございます。二次配列の値導入のイメージが分かっておらず、お聞きした次第です。
    行数は決まってはいません。質問内容を明確にするために追加修正の中にはあえて数字を固定して入れております。本来は数字は確定しておらず、ファイル内の情報が増えた分、柔軟にとりこめるようにしなければいけません。ここについてはファイルの中の行数を行数チェックでカウントして数字を取りました。

    キャンセル

  • 2019/09/22 10:47

    行数チェックって何するんだ?と思いましたが、行数が分かるならどちらでもいいです。

    キャンセル

0

回答

どういった方法が簡単でしょうか?
私は以下のようなアプローチをとったのですが、不要なものが多いような気がした

そのコードが「なぜ不要なものが多い」と感じたかを考えることが大事です。

個人的には不要なものがあるかどうかよりもコードが読みにくいことが気になります。
特に変数の命名やデータの保持方法辺りが気になります。

まずはそういった点を改善し、読みやすいコードを作ると良いでしょう。
ロジック的に不要なものがあるかどうかはその後に判断してはいかがでしょうか。

では、どのようにして読みやすいコードにするか。
改善策を下記に記載します。

改善案

人間の名前と友達一覧を持つクラスを定義して、そのリストを生成して読み込んだデータの管理をするのが良いでしょう。
使うのは配列ではなくリストです。配列よりもリストの方が要素数が不定のときの取り回しが効きます。

また、mainPersonyujinのように別々の変数で管理するのではなくオブジェクトで両方とも保持しておく方が人に理解しやすいコードを書けます。

例えば下記のようなUserクラスを定義します。

public class User{
    private String name;
    private List<String> friends;

    public User(String name, List<String> friends){
        this.name = name;
        this.friends = friends;
    }
}

プログラム上で下記のように読み取ります。

import java.util.*;
import java.lang.*;

public class Main {
    public static void main(String[] args) throws Exception {
        List<User> users = new ArrayList<User>();

        //input
        String listA = "Kate: Chris, Joe, Anna, Frank , Nancy\nChris: Kate, Nancy, Peter, Steve, Frank, Tim, Amy\nCharles: Sara, Kevin, Peter, Steve\nDavid: Steve, Amy , Bob \nFrank: Anna, Kate, Mary , Pop\nMax: Kate , Nancy , Tim\nSmith: Kevin, Kate, Tim, Bob";
        String[] rows = listA.toString().split("\n");
        for(String row : rows){
            String[] columns = row.split(":");
            List<String> friends = Arrays.asList(columns[1].split(","));
            String name = columns[0];
            User user = new User(name,friends);
            users.add(user);
        }

        //output
        for(User user: users){
            System.out.println(
                String.format(
                    "username:%-8s, friends:[%s]",
                    user.getName(),
                    String.join(",",user.getFriends())
                )
            );
        }
    }
}

出力結果

username:Kate    , friends:[ Chris, Joe, Anna, Frank , Nancy]
username:Chris   , friends:[ Kate, Nancy, Peter, Steve, Frank, Tim, Amy]
username:Charles , friends:[ Sara, Kevin, Peter, Steve]
username:David   , friends:[ Steve, Amy , Bob ]
username:Frank   , friends:[ Anna, Kate, Mary , Pop]
username:Max     , friends:[ Kate , Nancy , Tim]
username:Smith   , friends:[ Kevin, Kate, Tim, Bob]

改めて書きますが、修正したポイントは3つです。

  • 変数の命名を意味が分かるものにする
  • 読み込んだ文字列をオブジェクトとして管理する
  • 要素数が不明なときはListを使うと取り回しが効きやすい

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/22 04:56

    どうもありがとうございます。命名等、わかりやすく作るように心がけます。
    Listはまだ習っておらず、今回は二次元配列と配列のみでどうシンプルに作り上げるのか気になっておりました。

    キャンセル

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

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

関連した質問

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