治せない「クセ」を教えてください

例えばある配列内に

@moji = (ak, df, gc);

などという値でも文字でもが格納されていたとして、

$x = "ak";

といったある変数に格納されている値・文字(この場合はak)と一致する要素が配列@mojiに格納されていた場合に、その格納されている要素の添え字番号(配列の添え字番号)を返すような関数はないでしょうか?

イメージとして

$res = mch($x);

とすると、0が返されて$resに格納されるというものです。


ちなみにRという言語では

> a <- c("ljj", "B0", "op199") # 変数aに3つの文字列要素を代入する
> res <- which(a == "op199") # which()は引数に指定された論理に一致する要素番号を返す
> res # aについて,a == "op199"がTRUEとなるのは要素番号3であるから,3を返す
[1] 3

というものがあるのですが、これと同じような関数が欲しいのです(泣)

A 回答 (6件)

皆さんが既に答えられてますが…。


普通の関数として実装すればいいと思いますよ。
インデントは全角スペースになっています。


#!/usr/bin/perl
use strict;

my @moji = ('ak', 'df', 'gc');
my $x = "ak";
my $res = &mch($x, @moji);

# definedを使えば0番が返ったときでもTRUEになる
if(defined $res){
 print("found: $res\n");
}else{
 print("not found\n");
}

sub mch {
 my($key, @array) = @_;

 for(my $i = 0; $i < @array; $i++){
  if($key eq $array[$i]){
   return $i;
  }
 }

 return undef;
}
    • good
    • 1

すみません。

本気で間違えました!
送信した直後に気付きました。


正規表現部は全て
$moji[$_] =~ m/^\Q$x\E$/
としてください。

m/^\Q$x\E$/
これだけだと、添え字の「番号」に対して正規表現かけてました。
    • good
    • 0

Perlがよくわからないってことですか?


質問の趣旨とは違いますが、少し書いておきます。


#なんとか演算子 ..
(2 .. 5) #演算子名は忘れましたが、指定した連番からなるリストが返ります。
(2, 3, 4, 5,) #この記述と同等。


#配列変数に対し、スカラーを要求した場合、保持している要素の数を返します。
$scl = @ary; #要素数が10なら10が代入される。


# foreach (){}
条件判定部に与えられた「リスト」を順番に一つづつ取り出し、
{ } の中を実行する。
一つづつ取り出されたリストの中身は、明示的な指定がなければ
デフォルトの変数 $_ に代入されている。


#正規表現
m/ココの部分に正規表現を指定/;
検索対象の明示的な指定がなければ、$_ を対象として正規表現を行う。

-----------------------------------------------

以上を踏まえて、以下の記述で実現できます。
動作テストはしてません。

@moji = (ak, df, gc);
$x = "ak";

foreach ( 0 .. @moji - 1 ){ #-1とするのは、添え字は0から始まるため数字が1狂う。
m/$x/ and $res = $_; #正規表現でマッチが行われた場合、番号を代入。

}


-----------------------------------------------

実際に使う場合には、最初にマッチが行われた際、即座にループを終了する lastなどを書いたほうが良い。
もしくは、$res を配列変数にし、マッチが行われた番号を全て代入する、
などの処置をしたほうが良い。

-----------------------------------------------

まーテストはしてませんが、
Perlを分かってなさそうなので関数化した例もかいときます。
変数名や関数名は適当に直しといてください。

sub fnc ($@){
my $x = shift;
my @moji = @_;
my @ary; #戻り値

foreach ( 0 .. @moji - 1 ){
m/^\Q$x\E$/ and
push @ary, $_;
}

return @ary;
}

#※この関数が返す値は必ず配列です。
# スカラーでこの関数を要求した場合、マッチした個数が返ります。


# 呼び出しは以下のようになります。

@moji = (ak, df, gc);
$x = "ak";

@ary = fnc($x, @moji); # $x に マッチする @moji 全ての添え字を @ary に返す。

#この関数の場合、スカラーで求めるとマッチした「個数」が返るので間違わないで下さい。
$scl = fnc($x, @moji); #この場合、一個にマッチしたので$sclには 1 が返る。
    • good
    • 0

No.1さんとほととん同じですが、配列の要素数が大きい場合はこちらのほうが高速だと思います。



use List::Util qw(first);

my @moji = ("ak", "df", "gc");
my $x = "ak";

my $res = first { $moji[$_] eq $x } 0 .. $#moji;

print "$res\n";
    • good
    • 0

CPANのList::MoreUtilsを使用すれば値が一致するインデックスを返す


メソッド(firstindex)があります。
#標準ではこのモジュールはインストールされていないようですので、
#ご自分でインストールする必要があります。

例文を引用させてもらうと以下のよう動きになるそうです。
my @list = (1, 4, 3, 2, 4, 6);
printf "item with index %i in list is 4", firstidx { $_ == 4 } @list;

結果
item with index 1 in list is 4

参考URL:http://search.cpan.org/~adamk/List-MoreUtils-0.2 …
    • good
    • 0

添字を対象に grep 関数を用いると抜き出すことができます。



@moji = ("ak", "df", "gc");
$x = "ak";
($res) = grep { $moji[$_] eq $x } 0 .. $#moji;
print "$res\n";
    • good
    • 0

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


おすすめ情報