(define (find i . elements)
(if (eq? i (car elements)) 'Matched! (find2 i (cdr elements))))
(define (find2 i elements)
(if (eq? i (car elements)) 'Matched! (find2 i (cdr elements))))
上記を一つのfunctionにまとめることはできないでしょうか?
現在二つに分けている理由は(eq? i (car elements))が偽だったときに実行される(cdr elements)がリスト(例 '(a b c))なので、そのままfindを呼んでしまうとfindは(i . elements)を取るため、elementsが'((a b c))となってしまうからです。find2を使い、そのような「リストの中のリスト」を作らないようにしています。
find2を使わず一つにまとめられる方法はないでしょうか?お願いします。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
疑問が2つあります。
1.eq?でホントにいいの?
等価テストでeq?用いていますが、これはホントにポインタ使ってアドレス比較を行います。
つまり、例えばbと言う要素を(a b c)のから探したい、と言う場合、失敗する可能性がありますよ(いや、明らかに失敗するでしょう)。
と言うのも、bと'(a b c)の中のbは同じメモリにあるとは限らないから、です。
通常、推奨されるシンボル同士の比較にはeqv?を使います。こっちの方が若干判定条件が緩いです。また、比較対象が「数値限定」だったら=を使った方が良いですね。
2.find内定義でレストパラメータを利用している意味が明確じゃない。
必須パラメータの数がまず足りないのでは、と思いますね。
.(ドット)の後は、使用者が「入力しなくても構わないもの」と言うのが前提です。
そうなると、
(find 3)
の挙動はどう考えておられるのでしょうか?
これは、単に
(find 3 1 2 3 4 5 6 7 8 9)
と言うような入力を考慮してる設計でしょ?意味があるのかちょっと分からんのです(大体、見やすいか?とか思いますしね)。
平たく言うと、find2だけの設計で充分じゃないのか、と言うような気もします。
No.2
- 回答日時:
あああああ。
つい書いちゃったよ。;;; ここから
(define (find i element . elements)
(if (eqv? i element) ;必須パラメータ同士が eqv? だったら
'Matched! ;Matched! を返すのが基本動作
;; ローカル手続き loop を作る
(let loop ((elm elements)) ;レストパラメータのリストを elm に束縛
(and (pair? elm) ;レストパラメータが null じゃない事を確かめる
(or (find i (car elm)) ;トップレベルのfindをレストパラメータ無しで呼び出すか
(loop (cdr elm))))))) ;loop を elements の cdr に対して再帰呼び出し
;;; ここまで
;;; 実行例
> (find 3 3)
Matched!
> (find 0 1)
#f
> (find 3 3)
Matched!
> (find 0 1 2 3 4 5 6 7 8 9)
#f
> (find 3 1 2 3 4 5 6 7 8 9)
Matched!
> (find #\d #\a #\b #\c #\d #\e #\f)
Matched!
> (find #\a #\b #\c #\d #\e #\f #\g)
#f
>
No.3
- 回答日時:
しまった。
もう一本書いてしまった。ええと、memvと呼ばれる組み込み手続きがSchemeにはあります。
これは次のようにして使います。
> (memv 3 '(1 2 3 4 5 6 7 8 9))
(3 4 5 6 7 8 9)
> (memv 0 '(1 2 3 4 5 6 7 8 9))
#f
>
memvは、ある要素がリストの中にあるかどうか探し、あった場合はそれをcarとしたリストを、無かった場合は#fを返します(判定にはeqv?ば使われています)。
つまり、殆どfindの挙動と同じなんですよ。従って、レストパラメータが形作るリストに対して、素直にこれを適用しても結果は変わらない、と言う事です。
;;; ここから
(define (find i element . elements)
(and (or (eqv? i element) ;必須パラメータ同士を比較するか
(and (pair? elements) ;レストパラメータが null じゃない事を確認した後
(memv i elements))) ;i が elements 内にあるかどうか判定する
'matched!)) ;正しかったら matched! を返す
;;; ここまで
;;; 実行例
> (find 0 1)
#f
> (find 3 3)
matched!
> (find 0 1 2 3 4 5 6 7 8 9)
#f
> (find 3 1 2 3 4 5 6 7 8 9)
matched!
> (find #\d #\a #\b #\c #\d #\e #\f)
matched!
> (find #\a #\b #\c #\d #\e #\f #\g)
#f
>
No.4
- 回答日時:
おっと#3の訂正。
memvは空リストに対しても正常に動作しますね。
> (memv 3 '())
#f
>
と言うことはレストパラメータの中身がどうなのか、確認せんでもエエって事ですね。
(define (find i element . elements)
(and (or (eqv? i element) ;必須パラメータ同士を比較する
(memv i elements)) ;i が elements 内にあるかどうか判定する
'matched!)) ;正しかったら matched! を返す。
;;; 実行例
> (find 0 1)
#f
> (find 3 3)
matched!
> (find 0 1 2 3 4 5 6 7 8 9)
#f
> (find 3 1 2 3 4 5 6 7 8 9)
matched!
> (find #\d #\a #\b #\c #\d #\e #\f)
matched!
> (find #\a #\b #\c #\d #\e #\f #\g)
#f
;;; ここまで
なんで、これが一番コードとしては短いかな?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Photoshop(フォトショップ) Photoshop ElementsだとiPhoneで撮影した写真を加工して家にあるプリンターで印画 1 2022/10/30 12:17
- JavaScript 指定したパスが現URLに含まれていたら特定要素を削除するJavascriptのコードを教えてください 2 2023/04/27 17:58
- 英語 「第1および第2の要素」の英語 4 2022/03/24 09:55
- ドイツ語 提示の名言の文の構造について 2 2022/11/11 13:00
- その他(プログラミング・Web制作) python のヘルプの疑問。 1 2022/12/11 14:54
- 英語 語句節などの言葉の単位のことを、英語でなんと言いますか。 また、文の要素はElements of a 4 2023/06/26 14:38
- Visual Basic(VBA) ローマ字、ハイフン付きの並び替え ローマ字抽出方法 Excelマクロ 4 2022/04/01 14:10
- Photoshop(フォトショップ) pngファイル内の複数の画像を1個1個取り出す 5 2023/08/27 02:56
- Excel(エクセル) ExcelのVBAコードについて教えてください。 1 2022/06/20 09:22
- Excel(エクセル) アウトラインの小計のやり方 1 2023/03/20 11:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ファイル名の日付について教え...
-
C#で他のPCのサービスの起動...
-
再質問 コンボボックス リス...
-
if文の条件に関数が入ってる場...
-
VB.NETで他のEXEを実行させる
-
onedriveで同期解除をしたら、...
-
Edgeでダウンロード状況表示画...
-
沢山のフォルダにあるファイル...
-
vlan internal allocation poli...
-
USBデータの消失
-
WindowsからSSHでサーバーにあ...
-
壁紙・スクリーンセーバーの削...
-
Excel VBAでほかのアプリケーシ...
-
USB内のフォルダが「ファイル」...
-
共有しているファイルを削除し...
-
マイドキュメントのフォルダの...
-
YAHAMA RTXシリーズのコマンド...
-
スマホの電話帳vcfを携帯で読み...
-
ファイルを閉じるコマンドを教...
-
読み取り専用ファイルを上書き...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NETで他のEXEを実行させる
-
if文の条件に関数が入ってる場...
-
ファイル名の日付について教え...
-
C#で他のPCのサービスの起動...
-
再質問 コンボボックス リス...
-
シェルスクリプトに引数を渡す...
-
Word・Excelの「Ctrl+Y」につい...
-
Schemeで複数の関数を連続で実...
-
マシンをスタンバイの状態にし...
-
Audioサービスが実行されていま...
-
VBSでクエリを実行→クエリでテ...
-
onedriveで同期解除をしたら、...
-
vlan internal allocation poli...
-
沢山のフォルダにあるファイル...
-
マイドキュメントのフォルダの...
-
YAHAMA RTXシリーズのコマンド...
-
共有しているファイルを削除し...
-
teratarmでコマンド入力すると...
-
WindowsからSSHでサーバーにあ...
-
読み取り専用ファイルを上書き...
おすすめ情報