1

データが次のように形成されているパイプ区切りのフラットファイルで、一意の名前と最後の出現を (データから) カウントする最も賢明な方法は何ですか?

Artist|YYYY-MM-DD|Location|\n

たとえば、データが次の場合(最後に改行がある場合):

The Band|2011-04-01|Club Bulc|
Le Artist|1999-12-24|Reindeer Row|
Soundmakers|2012-03-22|Pub Pizza|
The Band|2010-12-01|Someplace|
Soundmakers|2009-07-07|Faraway|
Soundmakers|2010-08-18|ShowEr|

望ましい形式は次のようになります。

Artist|Times listed|Latest year

フラットファイルをループして、次のデータを 2 番目のフラットファイルに取得するにはどうすればよいでしょうか。

Le Artist|1|1999|
Soundmakers|3|2012|
The Band|2|2011|

最初はとても簡単な仕事だと思っていましたが、少し難しいことがわかりました!

半分うまくいく実装が 1 つあります (一部の項目は 2 回書かれ、年が間違った行にあることもあります!)、これを達成するためのより良い方法があるかどうかを確認したいと思います。

これについては、OOP と手続き型の両方のアプローチを試しましたが、これまでのところ、手続き型でより良い結果が得られています。しかし、これは私の個人的な学習 (および使用) のためであるため、私にとって方法は実際には問題ではありません。

更新: ファイルのサイズは約 1 MB ですが、近い将来には 10 MB をはるかに下回ります。

4

3 に答える 3

1

まず、アーティスト名をキー、年のリストを値とする配列を作成します。

$grouped = array();

while (!feof($fd) && $line = fgets($fd)) {
    list($artist, $date) = explode('|', $line);
    list($year) = explode('-', $date);

    $grouped[$artist][] = $year;
}

次に、結果を出力します。

foreach ($grouped as $artist => $years) {
    printf("%s|%s|%s|\n", $artist, count($years), max($years));
}
于 2012-07-05T13:33:42.957 に答える
1

確かにかなり単純に見えます。結果を次のような配列に格納する必要があります。

$bands = array(
    'Le Artist' => array('count' => 1, 'year' => 1999),
    ...
);

を使用fgetcsvして、行を読み込んで同時に分割することができます。

$line = fgetcsv($fh, 0, '|');

次に、このアーティストが既にいるかどうかを確認し、カウントを増やします。

$artist = $line[0];
if (!isset($bands[$artist])) {
    $bands[$artist] = array('count' => 0, 'year' => null);
}
$bands[$artist]['count']++;

年については、爆発$line[1]して年を抽出し、それがより大きいかどうかを確認$bands[$artist]['year']し、そうであれば置き換えます。

于 2012-07-05T13:37:19.950 に答える
0

Here is the version I ended up using, and it works as I hoped for:

<?php
$file = 'seen.txt';
$shows = array();
$sourceData = file($file);
foreach($sourceData as $row) {
    list($date, $artist, $venue, $city, $country) = explode('|', $row);
    $year = date('Y', strtotime($date));
    if(!isset($shows[$artist])) {
        $shows[$artist] = array('count' => 1, 'year' => $year);
    } else {
        $shows[$artist]['count']++;
        if($shows[$artist]['year'] < $year) {
            $shows[$artist]['year'] = $year;
        }
    }
}
echo '<h1>Bands and Shows</h1>';
ksort($shows);
foreach($shows as $band => $data) {
    echo 'I have seen <b>',$band,'</b> perform ',$data['count'],' times, most recently in ',$data['year'],'<br/>';
}
?>
于 2012-07-05T18:37:11.030 に答える