-1

Fitbit からダウンロードしたデータでいっぱいの CSV ファイルがあります。CSV ファイル内のデータは、基本的な形式に従います。

<Type of Data>
<Columns-comma-separated>
<Data-related-to-columns>

ファイルのレイアウトの小さな例を次に示します。

Activities
Date,Calories Burned,Steps,Distance,Floors,Minutes Sedentary,Minutes Lightly Active,Minutes Fairly Active,Minutes Very Active,Activity Calories
"2016-07-17","3,442","9,456","4.41","12","612","226","18","44","1,581"
"2016-07-18","2,199","7,136","3.33","10","370","93","12","46","1,092"
...other logs
Sleep
Date,Minutes Asleep,Minutes Awake,Number of Awakenings,Time in Bed
"2016-07-17","418","28","17","452"
"2016-07-18","389","26","10","419"

現在、CSVParserApache Common のライブラリを使用してこのデータを調べています。私の目標は、これを Java オブジェクトに変換して、関連データを Json に変換できるようにすることです (別の Web サイトにアップロードするには Json が必要です)。CSVParserファイル内を反復処理するために使用できる反復子がCSVRecordsあります。したがって、基本的に、すべてのデータの「リスト」があります。
ファイルにはさまざまな種類のデータ (睡眠ログ、アクティビティ ログなど) が含まれているため、ファイルのサブセクション/サブリストを取得し、それをクラスに渡して分析する必要があります。

リストを反復処理して、ファイルの新しいセクション (アクティビティ、食品、睡眠など) を識別するキーワードを探す必要があります。ファイルの次の部分が何であるかを特定したら、次のカテゴリまで、次のすべての行を選択する必要があります。

さて、この質問の質問については、イテレータを使用して と同等のものを取得する方法がわかりませんList.sublist()。これが私が試してきたことです:

while (iterator.hasNext())
{
    CSVRecord current = iterator.next();
    if (current.get(0).equals("Activities"))
    {
        iterator.next(); //Columns
        while (iterator.hasNext() && iterator.next().get(0).isData()) //isData isn't real, but I can't figure out what I need to do.
        {
            //How do I sublist it here?
        }
    }
}

したがって、次CSVRecordが引用符で始まるかデータがあるかを判断し、次のカテゴリが見つかるまでループし、最後にファイルのサブセクションを (イテレータを使用して) 別の関数に渡して、正しいログで何かを行う必要があります。

編集

最初にwhile ループに変換してからListサブリスト化することを検討しましたが、それは無駄に思えました。私が間違っている場合は修正してください。

また、各セクションに続く行数が同じになるとは限りません。似ているかもしれませんが、完全に異なるパターンに従う食品ログもあります。ここに 2 つの異なる日があります。Foods通常のパターンに従いますが、フードログはそうではありません。

Foods
Date,Calories In
"2016-07-17","0"
"2016-07-18","1,101"

Food Log 20160717
Daily Totals
"","Calories","0"
"","Fat","0 g"
"","Fiber","0 g"
"","Carbs","0 g"
"","Sodium","0 mg"
"","Protein","0 g"
"","Water","0 fl oz"

Food Log 20160718
Meal,Food,Calories
"Lunch"
"","Raspberry Yogurt","190"
"","Almond Sweet & Salty Granola Bar","140"
"","Goldfish Baked Snack Crackers, Cheddar","140"
"","Bagels, Whole Wheat","190"
"","Braided Twists Honey Wheat Pretzels","343"
"","Apples, raw, gala, with skin - 1 medium","98"
"Daily Totals"
"","Calories","1,101"
"","Fat","21 g"
"","Fiber","13 g"
"","Carbs","202 g"
"","Sodium","1,538 mg"
"","Protein","28 g"
"","Water","24 fl oz"
4

1 に答える 1

1

必要なことを行う最も簡単な方法は、以前のカテゴリ データを記憶し、新しいカテゴリにヒットしたときに、以前のカテゴリ データを処理して次のカテゴリにリセットすることです。これはうまくいくはずです:

String categoryName = null;
List<List<String>> categoryData = new ArrayList<>();
while (iterator.hasNext()) {
    CSVRecord current = iterator.next();
    if (current.size() == 1) { //start of next category
        processCategory(categoryName, categoryData);
        categoryName = current.get(0);
        categoryData.clear();
        iterator.next(); //skip header
    } else { //category data
        List<String> rowData = new ArrayList<>(current.size());
        CollectionUtils.addAll(rowData, current.iterator()); //uses Apache Commons Collections, but you can use whatever
        categoryData.add(rowData);
    }
}
processCategory(categoryName, categoryData); //last category of file

その後:

void processCategory(String categoryName, List<List<String>> categoryData) {
    if (categoryName != null) { //first category of the file, skip
        //do stuff
    }
}

上記は、aList<List<String>>が処理したいデータ構造であることを前提としていますが、必要に応じて微調整できます。List<Iterable<String>>単純にプロセス メソッド ( CSVRecordimplements ) に渡して、Iterable<String>そこで行データを処理することをお勧めします。

これは間違いなくさらにクリーンアップできますが、開始する必要があります。

于 2016-07-18T20:57:00.997 に答える