配列内の一致する要素の添え字番号を返す関数について

このQ&Aのポイント
  • ある配列内の要素と一致する値または文字を指定した場合に、その要素の添え字番号を返す関数について質問です。
  • 具体的には、ある配列@moji内の要素が指定した変数$xの値または文字と一致する場合、その要素の添え字番号を返す関数を探しています。
  • R言語では、which()関数を使用することで同様の結果を得ることができるのですが、Perlで同じような機能を持つ関数があるか教えていただきたいです。
回答を見る
  • ベストアンサー

一致する要素が格納されている添え字番号を返す

例えばある配列内に @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 というものがあるのですが、これと同じような関数が欲しいのです(泣)

  • backs
  • お礼率85% (564/660)
  • Perl
  • 回答数6
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • shiren2
  • ベストアンサー率47% (139/295)
回答No.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; }

その他の回答 (5)

  • SaLeeFA
  • ベストアンサー率66% (6/9)
回答No.5

すみません。本気で間違えました! 送信した直後に気付きました。 正規表現部は全て $moji[$_] =~ m/^\Q$x\E$/ としてください。 m/^\Q$x\E$/ これだけだと、添え字の「番号」に対して正規表現かけてました。

  • SaLeeFA
  • ベストアンサー率66% (6/9)
回答No.4

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 が返る。

  • ryu_chan
  • ベストアンサー率37% (69/186)
回答No.3

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";

  • diszo
  • ベストアンサー率78% (32/41)
回答No.2

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.26/lib/List/MoreUtils.pm
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.1

添字を対象に grep 関数を用いると抜き出すことができます。 @moji = ("ak", "df", "gc"); $x = "ak"; ($res) = grep { $moji[$_] eq $x } 0 .. $#moji; print "$res\n";

関連するQ&A

  • [C言語] 配列が添字の意味を失う理由

    はじめまして。こんばんは。 早速ですが、下記のソースコードは、 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 という内容の、C言語のプログラムです。(C++でコンパイルするためmain()はint型に指定) そこで、このプログラムを実行していて腑に落ちない点として、 プログラムの挙動を見る限り、 タイトルに書いたとおり、 「配列が添字の意味を失っている」という事なんです。 普通に配列の添字と考えれば、 while文の条件式は、 int i=0; while(a[i]) { i++; } なので、a[0]になるはずなので、 普通に考えれば 条件式の中身としては  配列a[0] が 配列a[0] になるまでi++をするとなるはずです。 しかしながら、このプログラムは、 初期値に「0」が入っている要素まで探し続けます。 なぜ、 「配列が添字の意味を失うのか?」 どなたか、この疑問にお答えしていただけますと幸いです。 「プログラムの内容」 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 「表示結果」 a[2]= 0 「ソースコード」 #include<stdio.h> int main() { int a[]={3,0,7,8,5,5,8}; int i=0; while(a[i]) { i++; } printf("a[%2d]=%2d \n",i,a[i]); }

  • 2つの配列要素を比較して、一致しない要素を別配列にしたい

    配列A、配列B、配列C と仮にします。 配列Aから、配列Bと一致しなかった要素の値を配列Cに入れる (一致した分を除外したい) みたいなことをデータベースを使用せずに、Perlで実現したいのですが可能でしょうか?

    • ベストアンサー
    • Perl
  • 通常の添字か連想添字かの判別

    $hoge = array('a', 'b'); の場合、 array([0] => 'a', [1] => 'b') となり、 $hoge = array('abc' => 'a', 'def' => 'b') の場合、 array(['abc'] => 'a', ['def'] => 'b') という格納結果になると思いますが、 ここでその格納されている配列の添字がインデックスなのか 連想添字なのかの判別をしたいです。 添字をis_numeric()で判別しようかと思いましたが、 $hoge = array('456' => 'a', '789' => 'b') などと指定されていた時、それは連想添字でないという 判別になってしまい、それはそれで困ります。 (今作っている機能の性質上、そんな事をする人は滅多にいないとは 思いますが) これをどうにか綺麗に判別する方法などありますでしょうか? それともそういうデータの受け渡しを許可している作りを 見直す、という方向になってしまうのでしょうか?

    • ベストアンサー
    • PHP
  • ハッシュの中に格納された配列の要素数を得る方法

    予想配列のあるキーを配列とします。 %hash; @hash{'a'}=['aa','ab','ac']; 一方で普通の配列をスカラ変数として扱うと配列数を表します。 @array=(a,b,c,d,e); $num=@array; # $numは5になる。 それでは $num=@hash{'a}; あるいは  $num=@{hash{'a'}}; としたらどうなるのって ARRAY(0x2438c4) みたいになって、$numに@hash{'a'}の要素数は入りません。 予想配列の中に格納された配列の要素数を取り出す簡便な方法はないものでしょうか。 お手数をお掛けします。

    • ベストアンサー
    • Perl
  • ファイル内の文字を配列に格納

    ファイル内の文字列をも表示させた上で、文字列を配列に1つずつ格納したいのですが、とっても簡単な方法で教えてください。 ファイル名は「abc」で配列名は「moji」でお願いします。

  • [マクロ]配列を区切り文字で変数に格納する方法

    タイトルの通りなのですが、 例えば、 A1~B10にランダムな数字が入っています。 (1)A1~B10を配列Cに格納します。 (2)配列C(1,10)を変数test1に格納します。  ※その時に各配列を/で区切る (3)配列C(2,20)を変数test2に格納します。  ※その時に各配列を/で区切る (4)test1をセルC1に記入 (5)test2をセルC1に記入 のような感じです。 配列に格納する方法はさすがに分かるのですが、区切り文字を入れて変数に格納する方法が分かりません。。。。 ご教授お願いいたします。

  • if文の判定条件('||'と'&&'の使い方)

    ○if文の判定条件への理解が弱いため、下記プログラムを作成し、 疑問があったため、質問をしたいと思っております。 #include<stdio.h> #include<string.h> int main() { char moji[]= "A"; /***********************************************************/ if( 0 != strcmp( moji , "A" ) || strcmp( moji , "B" ) ) ^^(1) /***********************************************************/ { printf( "文字不一致" ); } else { printf( "文字一致" ); } return (0); } ○質問 「/*/」で囲ったif文の判定箇所になりますが、 この判定条件は"配列mojiに格納されている値が"A",または"B"以外の" ときに、画面上に「文字不一致」を出力します。そうでなければ 「文字一致」を出力します。 今回、配列mojiには"A"が格納されており、「文字一致」が画面に 出力されるはずですが、「文字不一致」が出力されてしまいます。 判定条件が誤っていると思い、色々と試したところ、(1)の箇所を 「&&」にしたときに、「文字不一致」が出力されます。 「||」(論理和)と「&&」(論理積)が理解できていないと思われ、 この部分を交えて、何故「&&」にしないと「画面不一致」と出力 されないのかを、ご教授の程お願い致します。

  • 配列の要素番号を取得するには?

    悩んでいることがあり、皆さんのお力を貸しください。 double[31]という配列を作り、各要素にある条件で値が格納されます。その後、この値の中から最大値を求める式を書き、最大値を求めます。ここまではなんとかできるのですが、この最大値を得た時の要素番号も表示したいのです。 求められた値から、要素番号を求める事はできるのでしょうか? わかる方にはなんてことないと思いますが、初心者のため悩みまくっています。どうかお力を貸してください。お願いします。

  • 配列要素の並べ替え

    $Res[$i]という配列に、数字の要素が入っているんですが、それを昇順で並べ替えして要素の間に/を入れたいのですが、 foreach (sort {$a cmp $b} keys %Res) { $Res2 = $Res[$i] + "/" } どうもこの記述では上手くいかないので、どなたか教えて下さい!!

    • ベストアンサー
    • Perl
  • 変数に格納されている特定の文字列のフィールド番号を抜き出したいと考えて

    変数に格納されている特定の文字列のフィールド番号を抜き出したいと考えております。 お世話になります。 現在、変数に格納されている特定の文字列のフィールド番号を抜き出したいと考えております。 例として下記名前を指定した変数が有るとします。 NAMEFILE="愛 麻衣 美衣 魔印" このとき「美衣」をgrepすると「3」を言う数値を返したいと考えております。 色々探して「match関数の RSTART」にて行いたい事と近い事が出来たのですが、 開始文字を抜き出す為、かえってくる数値は「6」となってしまいます。 行いたい事として、この場合区切り文字をスペースとし左側から数を抜き出したいのですが 何か良い情報は有りませんでしょうか。 知恵をお借りできたらと存じます。よろしくお願い致します。