アプリ版:「スタンプのみでお礼する」機能のリリースについて

お世話になります。

二桁の数字からなる配列数10個内に00がある場合、十の位と一の位をそれぞれ取り出すようにテスト中なのですが、配列内に00がある場合、十の位と一の位の数字がコピーされてしまうようです。

#!/usr/bin/perl

@Array="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";
foreach$i(0..$#Array){
@Mtmp=split(/<>/,$Array[$i]);
}

foreach$i(0..$#Mtmp){
($M_old_9,$M_old_8,$M_old_7,$M_old_6,$M_old_5,$M_old_4,$M_old_3,$M_old_2,$M_old_1,$M_old_0)=split(/<>/,$Mtmp[$i]);
# if($Mtmp[$i] != ''){
$M_n = substr ("$Mtmp[$i]", -2);#■二桁のの数字
$M_t10=$M_n;
$M_t1 = substr ("$M_t10", -1 , 1);#■一の位を取り出し
chop$M_t10; #■十の位を取り出し
$acount++;
# }
print "No.$i $Mtmp[$i]\n";
$M_yosou++;

$M_old_9=$M_old_8;
$M_old_8=$M_old_7;
$M_old_7=$M_old_6;
$M_old_6=$M_old_5;
$M_old_5=$M_old_4;
$M_old_4=$M_old_3;
$M_old_3=$M_old_2;
$M_old_2=$M_old_1;
$M_old_1=$M_old_0;
$M_old_0=$M_n;#■二桁のの数字

$M_old_n9_10=$M_old_n8_10;
$M_old_n8_10=$M_old_n7_10;
$M_old_n7_10=$M_old_n6_10;
$M_old_n6_10=$M_old_n5_10;
$M_old_n5_10=$M_old_n4_10;
$M_old_n4_10=$M_old_n3_10;
$M_old_n3_10=$M_old_n2_10;
$M_old_n2_10=$M_old_n1_10;
$M_old_n1_10=$M_old_n0_10;
$M_old_n0_10=$M_t10;#■十の位

$M_old_n9_1=$M_old_n8_1;
$M_old_n8_1=$M_old_n7_1;
$M_old_n7_1=$M_old_n6_1;
$M_old_n6_1=$M_old_n5_1;
$M_old_n5_1=$M_old_n4_1;
$M_old_n4_1=$M_old_n3_1;
$M_old_n3_1=$M_old_n2_1;
$M_old_n2_1=$M_old_n1_1;
$M_old_n1_1=$M_old_n0_1;
$M_old_n0_1=$M_t1;#■一の位
}

print "\$acount=$acount\n<br>\@Mtmp=@Mtmp \n<br>\$M_n=$M_n \n<br>\$M_t10=$M_t10 \n<br>\$M_t1=$M_t1 \n<br>\$M_old_9=$M_old_9\n<br>\$M_old_8=$M_old_8\n<br>\$M_old_7=$M_old_7\n<br>\$M_old_6=$M_old_6\n<br>\$M_old_5=$M_old_5\n<br>\$M_old_4=$M_old_4\n<br>\$M_old_3=$M_old_3\n<br>\$M_old_2=$M_old_2\n<br>\$M_old_1=$M_old_1\n<br>\$M_old_0=$M_old_0\n<br>\$M_old_n9_10=$M_old_n9_10\n<br>\$M_old_n8_10=$M_old_n8_10\n<br>\$M_old_n7_10=$M_old_n7_10\n<br>\$M_old_n6_10=$M_old_n6_10\n<br>\$M_old_n5_10=$M_old_n5_10\n<br>\$M_old_n4_10=$M_old_n4_10\n<br>\$M_old_n3_10=$M_old_n3_10\n<br>\$M_old_n2_10=$M_old_n2_10\n<br>\$M_old_n1_10=$M_old_n1_10\n<br>\$M_old_n0_10=$M_old_n0_10\n<br>\$M_old_n9_1=$M_old_n9_1\n<br>\$M_old_n8_1=$M_old_n8_1\n<br>\$M_old_n7_1=$M_old_n7_1\n<br>\$M_old_n6_1=$M_old_n6_1\n<br>\$M_old_n5_1=$M_old_n5_1\n<br>\$M_old_n4_1=$M_old_n4_1\n<br>\$M_old_n3_1=$M_old_n3_1\n<br>\$M_old_n2_1=$M_old_n2_1\n<br>\$M_old_n1_1=$M_old_n1_1\n<br>\$M_old_n0_1=$M_old_n0_1\n<br><br>";
__END__;

上記の実行結果は
# perl test3.cgi
No.0 10
No.1 78
No.2 51
No.3 78
No.4 00
No.5 72
No.6 43
No.7 82
No.8 65
No.9 29
$acount=10
<br>@Mtmp=10 78 51 78 00 72 43 82 65 29
<br>$M_n=29
<br>$M_t10=2
<br>$M_t1=9
<br>$M_old_9=
<br>$M_old_8=
<br>$M_old_7=
<br>$M_old_6=
<br>$M_old_5=
<br>$M_old_4=
<br>$M_old_3=
<br>$M_old_2=
<br>$M_old_1=
<br>$M_old_0=29
<br>$M_old_n9_10=1
<br>$M_old_n8_10=7
<br>$M_old_n7_10=5
<br>$M_old_n6_10=7
<br>$M_old_n5_10=0
<br>$M_old_n4_10=7
<br>$M_old_n3_10=4
<br>$M_old_n2_10=8
<br>$M_old_n1_10=6
<br>$M_old_n0_10=2
<br>$M_old_n9_1=0
<br>$M_old_n8_1=8
<br>$M_old_n7_1=1
<br>$M_old_n6_1=8
<br>$M_old_n5_1=0
<br>$M_old_n4_1=2
<br>$M_old_n3_1=3
<br>$M_old_n2_1=2
<br>$M_old_n1_1=5
<br>$M_old_n0_1=9
<br><br>
なのですが、上記の00を取り出した部分がなぜか十の位と一の位どちらもコピーされてしまいます。
これはなぜこのような症状がおきるのでしょうか。また00の際も十の位と一の位それぞれ0を取り出すにはどのようにすれば宜しいでしょうか。

2.下記の
$M_old_9=
...
$M_old_0=
の所が二桁の数字が順次展開されないのは何故なのでしょうか。

お忙しいかとは存じますが、よろしくお願い致します。

A 回答 (4件)

何で配列を使わずに妙な番号のついた通常の変数を山盛り使ってるんでしょうか。



とりあえず下二桁を逆順に出していると言うことで

#!/usr/bin/perl
# -*- coding: utf8 -*
use strict;
use warnings;
use Fatal qw(:void open close);
use feature ':5.10';

#use utf8;
#use Encode qw/from_to decode encode/;



while (my $line = <DATA>) {
chomp $line;

my @array = split /<>/, $line;
my $itemcount = 0;

foreach my $item (@array) {
say "No. $itemcount $item";
$itemcount++;
}

say "\$itemcount=$itemcount";

my $outstring1;
my $outstring2;
my $outstring3;
foreach my $item (reverse @array) {
$outstring1 .= "<br>$item\n";

my $d1 = chop $item;
my $d10 = chop $item;
$itemcount--;
$outstring2 .= "<br>M_${itemcount}_10=$d10\n";
$outstring3 .= "<br>M_${itemcount}_1=$d1\n";
}

say $outstring1;
say $outstring2;
say $outstring3;
}

__END__
10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>

No. 0 10
No. 1 78
No. 2 51
No. 3 78
No. 4 00
No. 5 72
No. 6 43
No. 7 82
No. 8 65
No. 9 29
$itemcount=10
<br>29
<br>65
<br>82
<br>43
<br>72
<br>00
<br>78
<br>51
<br>78
<br>10

<br>M_9_10=2
<br>M_8_10=6
<br>M_7_10=8
<br>M_6_10=4
<br>M_5_10=7
<br>M_4_10=0
<br>M_3_10=7
<br>M_2_10=5
<br>M_1_10=7
<br>M_0_10=1

<br>M_9_1=9
<br>M_8_1=5
<br>M_7_1=2
<br>M_6_1=3
<br>M_5_1=2
<br>M_4_1=0
<br>M_3_1=8
<br>M_2_1=1
<br>M_1_1=8
<br>M_0_1=0

あんまり短く書いてもわけわからないでしょうからとりあえずこんなところで。

この回答への補足

ご教授頂きありがとうございます。

通常の変数てんこ盛りにつきましては、配列を使う為の頭の余裕がなかったものですから、通常の変数てんこ盛りで考えてしまったのです。しかしはやりと言うべきか当たり前に配列を使った方が簡単ですね。

下二桁を逆順に出している部分についても、上げていったカウントを下げてゆく辺りは非常に参考になりました。ありがとうございます。

また2桁の数字から、十の位と一の位をchopで切り取り取り出している事についても、勉強させて頂きました。

chopで削ると、最終的に配列の中身が空になるんですね。
ネット上では、行末の改行を削除・・・程度にしか乗っていない為、どうやって十の位を取り出しているのか疑問でなりませんでしたが、一回目のchopした後の$itemを参照する事で理解が得られました。
chop2回をそれぞれ代入することで意図した値が得られるのは私にとって必見でした。すごく参考になりました。ありがとうございます。

補足日時:2008/08/08 08:26
    • good
    • 0

まず、変数の名前の法則が分かりません。



$M_old_9=10
$M_old_8=78
$M_old_7=51
$M_old_6=78
$M_old_5=78
$M_old_4=72
$M_old_3=43
$M_old_2=82
$M_old_1=65
$M_old_0=29

$M_old_n の n の部分は逆順ですか?
(<>で分割した一番最後の要素が $M_old_0 で 一番最初の要素は
$#Mtmp に相当する?)

foreach(reverse(split(/<>/, $Mtmp[$i]))) {
push(@M_old, $_);
}

for(my $j = $#M_old; $j >= 0; $j--) {
print "\$M_old[$j] = $M_old[$j]\n";
}

こんな感じ?

$M_old_n9_10=1
$M_old_n8_10=7
$M_old_n7_10=5
$M_old_n6_10=7
$M_old_n5_10=7
$M_old_n4_10=7
$M_old_n3_10=4
$M_old_n2_10=8
$M_old_n1_10=6
$M_old_n0_10=2
$M_old_n9_1=0
$M_old_n8_1=8
$M_old_n7_1=1
$M_old_n6_1=8
$M_old_n5_1=8
$M_old_n4_1=2
$M_old_n3_1=3
$M_old_n2_1=2
$M_old_n1_1=5
$M_old_n0_1=9

ここがもっとよく分からない状態です。

$M_old_ni_n

の i と n はどういう法則ですか。

あと、条件文の

if($Mtmp[$i] != ''){

は間違っています。
文字列の比較演算子はPerlでは

if($Mtmp[$i] ne ''){

としないといけません。
(数値と文字列の比較演算子は別です)
他にも何カ所か記述を間違えているみたいですのでこのままでは
何をしたいのかよく分かりません。

この回答への補足

お忙しい中ご教授頂きありがとうございます。

>まず、変数の名前の法則が分かりません。
>$M_old_n の n の部分は逆順ですか?
仰るとおり、<>で分割した一番最後の要素が $M_old_0で一番最初の要素が$M_old_9に来るようにしております。
foreach$i(0..$#Mtmp){

$M_old_9=$M_old_8;
$M_old_8=$M_old_7;
$M_old_7=$M_old_6;
$M_old_6=$M_old_5;
$M_old_5=$M_old_4;
$M_old_4=$M_old_3;
$M_old_3=$M_old_2;
$M_old_2=$M_old_1;
$M_old_1=$M_old_0;
$M_old_0=$M_n;#■二桁のの数字
..
}
と$#Mtmpの数だけループさせることで、必然的に過去の数字を代入させていってるのですけれども・・。

また
>$M_old_ni_n
>
>の i と n はどういう法則ですか。

部分も同様に、(前回でも補足説明させて頂いておりますが)
頭の部分で十の位と一の位を抜き出し、変数に代入したい考えからでございます。
その為、一の位は$M_old_n?_1とし十の位は$M_old_N?_10とするようにしております。

また
>こんな感じ?
部分を参考に下記のようなスクリプトで実行した結果ですが、
#!/usr/bin/perl

@Array="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";
foreach$i(0..$#Array){
@Mtmp=split(/<>/,$Array[$i]);
}
foreach(reverse(split(/<>/, $Mtmp[$i]))) {
push(@M_old, $_);
}

for(my $j = $#M_old; $j >= 0; $j--) {
print "\$M_old[$j] = $M_old[$j]\n";
}
__END__;

> $M_old[0] = 10
と表示される形でした。
$M_old[0]..$M_old[9]までは表示されないようでございました。
でも、foreachやfor構文を使えば、簡単に実現できそうな印象を受けますね。ありがとうございます。

>あと、
>..
>Perlでは
>if($Mtmp[$i] ne ''){
>としないといけません。
そうですね。数字として扱えているものと考えておりましたので、そのようにしておったのですが、文字として扱っているんでしょうか・・。
だとすると、意図して数字として扱うにはどうすればよいのか・・・と疑問が沸いてしまいます。

補足日時:2008/08/07 16:58
    • good
    • 0
この回答へのお礼

>for(my $j = $#M_old; $j >= 0; $j--) {
>print "\$M_old[$j] = $M_old[$j]\n";
>}
改めまして、ご教授頂きましたようにfor構文にて逆順に表示させてゆく事ができるんですね。

参考になりました。ありがとうございます。

お礼日時:2008/08/08 07:33

あ、ANo1の補足。



@Array="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";



$Array[0]="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";

ですよね。

foreach$i(0..$#Array){
@Mtmp=split(/<>/,$Array[$i]);
}

こうすると @Mtmp の中身は

@Mtmp = (10, 78, 51, 78, '00', 72, 43, 82, 65, 29, '');

となります。
この時点で

($M_old_9,$M_old_8,$M_old_7,$M_old_6,$M_old_5,$M_old_4,$M_old_3,$M_old_2,$M_old_1,$M_old_0)=split(/<>/,$Mtmp[$i]);

これは意味がないですよね。
(そもそも、上記のループ内で上書きしているので実際に配列数が
複数ある場合最後しか取得できません)

他にもなんかだ訳が分からない状態ですので再度見直してみてください。

この回答への補足

>$Array[0]="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";
>
>ですよね。
はい。

これは、数字.dat
という名前で下記のような一行の形で複数ファイル保存されておりまして、その一行を読み込む事を前提としている為です。
10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>

>($M_old_9,$M_old_8,$M_old_7,$M_old_6,$M_old_5,$M_old_4,$M_old_3,$M_old_2,$M_old_1,$M_old_0)=split(/<>/,$Mtmp[$i]);
>
>これは意味がないですよね。
>(そもそも、上記のループ内で上書きしているので実際に配列数が
>複数ある場合最後しか取得できません)

ですよね^^;最後しか取得できていなくて、しばし思考していました。(まだ良く分かっておりませんが・・)

>どうなって欲しいのかが分からないのでその理想の結果を
>書いていただけませんか。

理想の結果ですけれども、後、ついでにですが、質問当初の
>00がある場合、十の位と一の位の数字がコピーされてしまうようです。
は、質問している時点では、コピーされてない状態で質問しておりました。^^;申し訳ございません。
で、理想の結果をふまえまして、再現できるかやってみました所、
foreach$i(0..$#Mtmp){
#($M_old_9,$M_old_8,$M_old_7,$M_old_6,$M_old_5,$M_old_4,$M_old_3,$M_old_2,$M_old_1,$M_old_0)=split(/<>/,$Mtmp[$i]);#■コメントアウト
if($Mtmp[$i] != ''){#■■ここの#を外す■■
$M_n = substr ("$Mtmp[$i]", -2);#■二桁のの数字
$M_t10=$M_n;
$M_t1 = substr ("$M_t10", -1 , 1);#■一の位を取り出し
chop$M_t10; #■十の位を取り出し
$acount++;
}#■■ここの#を外す■■

2箇所の
#■■ここの#を外す■■
箇所の#を外す事で、質問当初の00部分の十の位と一の位がコピーされてしまう事を再現できました。

後、上記
#($M_old_9,$M_old_8,$M_old_7,$M_old_6,$M_old_5,$M_old_4,$M_old_3,$M_old_2,$M_old_1,$M_old_0)=split(/<>/,$Mtmp[$i]);
部分をコメントアウトした上で
#■■ここの#を外す■■を外さない事で一応理想の結果を得られている状態でございます。

実行結果
<br>$M_old_9=10・・・ここに各二桁の値が入り
<br>$M_old_8=78
<br>$M_old_7=51
<br>$M_old_6=78
<br>$M_old_5=78
<br>$M_old_4=72
<br>$M_old_3=43
<br>$M_old_2=82
<br>$M_old_1=65
<br>$M_old_0=29
<br>$M_old_n9_10=1
<br>$M_old_n8_10=7
<br>$M_old_n7_10=5
<br>$M_old_n6_10=7
<br>$M_old_n5_10=7・・・ここの部分と
<br>$M_old_n4_10=7
<br>$M_old_n3_10=4
<br>$M_old_n2_10=8
<br>$M_old_n1_10=6
<br>$M_old_n0_10=2
<br>$M_old_n9_1=0
<br>$M_old_n8_1=8
<br>$M_old_n7_1=1
<br>$M_old_n6_1=8
<br>$M_old_n5_1=8・・・ここの部分が0のはずなのですが、なぜコピーされるのかお分かりになりますでしょうか
<br>$M_old_n4_1=2
<br>$M_old_n3_1=3
<br>$M_old_n2_1=2
<br>$M_old_n1_1=5
<br>$M_old_n0_1=9

上記で行っている事は、二桁の数字を抜き出しまして、それを十の位と一の位の数字を切り分けて取り出し、各変数に埋め込みたい考えでございます。
無駄が多いのは、現段階の私のレベルでは仕方がないのかな・・と考えておりますが、無駄を省くことってできますか?
過去にご教授頂いた事を参考に
$M='M_old_';
${"$M"}{$acount}=$Mtmp[$i];
な感じで・・というイメージはあるのですが、案の定ハマってしまいました。

補足日時:2008/08/07 14:22
    • good
    • 0

なんか、どうなって欲しいのかが分からないのでその理想の結果を


書いていただけませんか。

@Array="10<>78<>51<>78<>00<>72<>43<>82<>65<>29<>";

これは配列でない(これでは配列にする意味がない)のですが実際には
ちゃんと複数入れているのでしょうか。

なんか上のコードは無駄が多すぎるような気がします。
ループとか使ってもう少し簡略化できませんか。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!