3

これが私がやろうとしていることの基本的な論理ですが、うまくいかないようです。

  1. アルファベットの配列をループします
  2. 文字ごとに、XMLをループし、プログラム名が現在の文字で始まり、メジャーがまだ出力の配列にない場合は、XMLからのデータを含むリンクを出力します。
  3. リンクが出力されるときはいつでも、出力の配列にメジャーを追加して、doubleを出力しないようにします

問題は、メジャーが配列内にある場合でも、次の行であるということです。

if (!in_array($program->Program, $majors)) {

は常にtrueを返し、doubleが出力されます。

現在、ページ上では、リンクが出力されるたびに、配列全体を出力して、メジャーが配列に存在することを視覚的に確認しています。メジャーWBANのページの下部に到達すると、最初の出力で確認できます。その上の配列で、それが配列に存在しないことを確認すると、出力されますが、次のリンク出力もWBANであり、その上の配列ですでに存在していることがわかります。したがって、ifはfalseを返し、出力しない...

私のロジックはどこかに欠陥があるはずです-array_pushをあちこちに動かそうとしましたが、正しく動作させることができません-新鮮な目が必要です。

また、間違っている場合は訂正してください。ただし、XMLから重複を削除できないのは、完全なXMLノードが重複していないためです。メジャーは重複しています。

たとえば、これがXMLです。ProgramとMajorDescriptionのみが複製されるため、完全なXMLノードは複製とは見なされません。

<ProgramList>
    <MajorDescription>WEB ANIMATION AND DESIGN</MajorDescription>
    <Program>WBAN</Program>
    <ProgramLocations>
        <ProgramLocation>
            <Campus>Barrie</Campus>
        </ProgramLocation>
    </ProgramLocations>
    <Term>201310</Term>
</ProgramList>

完全なコード:

<?php 
$majors = array();
foreach ($alphabet as $l){
    $upper = strtoupper($l);                            

    foreach ($listxml->ProgramList as $program) {
        $letter = substr($program->MajorDescription, 0, 1);
        if (strcasecmp($letter, $l) == 0) {
            $count1++;
            $noprograms = false;
        }                               
    }

    if ($count1 == 0) {
        echo "<div id='$l' class='letter noprograms'>"; 
    } else {
        echo "<div id='$l' class='letter'>";
    }                           

    echo "<h2>$upper</h2>";

    foreach ($listxml->ProgramList as $program) {                             
        $letter = substr($program->MajorDescription, 0, 1);                

        if (strcasecmp($letter, $l) == 0) { 

            foreach ($majors as $major){
                echo "<p>".$major."</p>";
            }                  
            //this is where the problem is - this is always coming back true even if the major is in the array 
            if (!in_array($program->Program, $majors)) {                                    
                echo "<a href='../program/?major=".$program->Program."' class='programLink'>".$program->Program." - ".strtoupper($program->MajorDescription)."</a> - <a target='_BLANK' href='http://www.ontariocolleges.ca/SearchResults/GEORGIAN/_/N-1z1419r?Ntt=".rawurlencode($program->MajorDescription)."&Ns1=Program_Title_SORT&Ns2=0&Qo=20&SearchWithin=on'>Apply Now</a><br />";                                                                                                           
                array_push($majors, $program->Program);
            }                                                                       
            $count++;                                   
        }                               
    }
    if ($count == 0) {
        echo "<em class='noprograms'>No Programs</em><br />";
    }
    echo "</div>";                      
    $count = 0;
    $count1 = 0;
}

if ($noprograms) {
    echo '<div id="noprograms"><em>No results. Try broadening the search filters.</em></div>';
}
?>
4

3 に答える 3

2

ノードを文字列値にキャストする必要があります。

if (!in_array((string)$program->Program, $majors)) {

と:

array_push($majors, (string)$program->Program);

これは、SimpleXML を使用するときに慣れなければならないことの 1 つです。暗黙的に変数を文字列にキャストする関数は、この特別な処理を必要としませんが、もしあなたが本当に偏執的であれば、すべてをキャストすることをお勧めします;-)

たとえばsubstr()、最初の引数が文字列であると予想され、自動的にキャストされるため、キャストは必要ありません。

于 2012-09-28T15:03:12.627 に答える
1

if (!in_array($program->Program, $majors, true)) {
                                          ^^^^

in_arrayは厳密なパラメータを持っているので、オブジェクトを扱うときに使用する必要があります(あなたがそうするように)。

別の選択肢はSplObjectStorageです。

$majors = new SplObjectStorage;

$majors->containts($program->Program);

$majors->attach($program->Program);

そして最後に重要なバリエーション:

$programName = (string) $program->Program;

isset($majors[$programName]);

$majors[$programName] = 1;
于 2012-09-28T15:14:13.370 に答える
0

よくわかりませんが、この部分に問題があると思います:

foreach ($listxml->ProgramList as $program) {                             
    $letter = substr($program->MajorDescription, 0, 1);                

    if (strcasecmp($letter, $l) == 0) { 

        foreach ($majors as $major){
            echo "<p>".$major."</p>";
        }                  
        //this is where the problem is - this is always coming back true even if the major is in the array 
        if (!in_array($program->Program, $majors)) {                                    
            echo "<a href='../program/?major=".$program->Program."' class='programLink'>".$program->Program." - ".strtoupper($program->MajorDescription)."</a> - <a target='_BLANK' href='http://www.ontariocolleges.ca/SearchResults/GEORGIAN/_/N-1z1419r?Ntt=".rawurlencode($program->MajorDescription)."&Ns1=Program_Title_SORT&Ns2=0&Qo=20&SearchWithin=on'>Apply Now</a><br />";                                                                                                           
            array_push($majors, $program->Program);
        }                                                                       
        $count++;                                   
    }                               
}

の各要素について、$listxml->ProgramListすべての$majors.

あなたは入れようとするべきです

        foreach ($majors as $major){
            echo "<p>".$major."</p>";
        }

ループの後にforeach ($listxml->ProgramList as $program) {ループします。

また、同じテストを 2 回行います。

foreach ($listxml->ProgramList as $program) {                             
    $letter = substr($program->MajorDescription, 0, 1);                

    if (strcasecmp($letter, $l) == 0) { 

両方のブロックを組み合わせることで、スクリプトを少し最適化できるのではないでしょうか?

于 2012-09-28T15:07:35.967 に答える