spliceを使って配列の要素を比較し入れ替えるには?

[上に] [前に] [次に]
riko 2000/04/05(水) 00:05:54
「datafile.dat」に格納されている情報をフォームから得た情報と比較し同じ要素があれば、入れ替えてなければ、追加したいのですが上手くいきません。
spliceを使って処理する方法があるようですが、(??)
どなたかアドバイス頂けないでしょうか?

「datafile.dat」の内容
A,3
B,2
C,6

フォームからA,5を得たときは、「A,3」と入れ替える。
A,5
B,2
C,6

フォームからD,8を得たときは、追加する。
A,3
B,2
C,6
D,8

以下、検討中のスクリプトです。

#!/usr/local/bin/perl

        require 'jcode.pl';
        $data = './datafile.dat';

if ($ENV{'SERVER_SOFTWARE'} =~ /^AnWeb/) {$flock ='';}

省略

$alphabet = $FORM{'alphabet'};
$count = $FORM{'count'};

print "Content-type: text/html\n\n";
print <<"EOF";
<html><head>
<title>SPLICE</title></head><BODY>
EOF

###########################################
splice(array,offset,length,list)
###########################################

open(IN, "$data");
    while ($_ = <IN>) {
if($_->[1] == $alphabet){
$_->[2] = $count
}elsif ($_->[1] != $alphabet) {
open(OUT,">>$data");
print(OUT "$alphabet,$count\n");
close(OUT);
}
print "$_<br>";
}
close(IN);

print "</body></html>\n";
exit;

しなのむし 2000/04/05(水) 03:31:20
やりたいのはこんなことでしょうか?
全然、splice使ってませんが・・・


$overwrite = "$alphabet,$count\n";

open(INOUT, "+< $data");

@lines = <INOUT>;

truncate(INOUT, 0);
seek(INOUT, 0, 0);

for(@lines)
{
($alphabet_dat,$count_dat) = split(/,/);

if($alphabet_dat eq $alphabet)
{
print INOUT $overwrite;
$overwrite = "";
}

else
{
print INOUT $_;
}
}
print INOUT $overwrite;

close(INOUT);

riko 2000/04/05(水) 14:38:11
ありがとうございました。
さっそく少し応用を試みたのですが、なぜか思うようにいきません。
大変恐縮ですが、今一度アドバイス頂けないでしょうか。

条件
1.フォームから得た$alphabetが等しくかつ$countの値が多きい時は書き換え。
2.フォームから得た$alphabetが等しくかつ$countの値が小さい時は何もしない。
3.フォームから得た$alphabetがない時は追加。

以下のスクリプトで実施すると上記2の条件の時、追加されてしまいます。




if(($alphabet_dat eq $alphabet) && ($count_dat < $count))
{print INOUT $overwrite;
$overwrite = "";
}elsif (($alphabet_dat eq $alphabet) && ($count_dat > $count)) {
print "you bad<br>";
}else{
print INOUT $_;
}
}
print INOUT $overwrite;
close(INOUT);

$r=$r+1;
open(IN, "$data");
while ($_ = <IN>) {
print "$r $_<br>";
$r=$r+1
}
close(IN);
print "</body></html>\n";
exit;

aki 2000/04/05(水) 18:09:45
上のとは違うやりかたですけど

open(IN,"$data")||die "cannot open $data";
@lines = <IN>;
close(IN) ;

for(@lines){
  chomp;
  ($alphabet_dat,$count_dat) = split(/,/);
  $list{$alphabet_dat} = $count_dat ;
}

if($list{$alphabet} < $count){
  $list{$alphabet} = $count ;
}

open(OUT,">$data")||die "cannot open $data";
foreach $keys (keys (%list)){
  print OUT "$keys,$list{$keys}\n";
}
close(OUT) ;

実行するたびにリストの順番が変わっちゃうけど
それがまずかったらHTMLに出力する前にsortとかして下さいね。

しなのむし 2000/04/05(水) 20:39:38
なんか条件が増えたんですか。
とりあえず、前の自分のの修正です。
(順番は変わらないはず)

$overwrite = "$alphabet,$count\n";

open(INOUT, "+< $data");

@lines = <INOUT>;

truncate(INOUT, 0);
seek(INOUT, 0, 0);

for(@lines)
{
($alphabet_dat,$count_dat) = split(/,/);

    if($alphabet_dat eq $alphabet)
    {
        if($count_dat < $count)
        {print INOUT $overwrite;}
        else
        {print INOUT $_;}

    $overwrite = "";

    }
    else
    {print INOUT $_;}
}
print INOUT $overwrite;

close(INOUT);

exit;

[上に] [前に] [次に]