Menu: Difference between revisions

81,321 bytes added ,  22 days ago
 
(212 intermediate revisions by more than 100 users not shown)
Line 1:
{{task|Text processing}}
Given a list containing a number of strings of which one is to be selected and a prompt string, create a function that:
 
;Task:
* Print a textual menu formatted as an index value followed by its corresponding string for each item in the list.
Given a prompt and a list containing a number of strings of which one is to be selected, create a function that:
* Prompt the user to enter a number.
* Return the string corresponding to the index number.
 
* prints a textual menu formatted as an index value followed by its corresponding string for each item in the list;
The function should reject input that is not an integer or is an out of range integer index by recreating the whole menu before asking again for a number. The function should return an empty string if called with an empty list.
* prompts the user to enter a number;
* returns the string corresponding to the selected index number.
 
<br>
For test purposes use the four phrases: “<tt>fee fie</tt>”, “<tt>huff and puff</tt>”, “<tt>mirror mirror</tt>” and “<tt>tick tock</tt>” in a list.
The function should reject input that is not an integer or is out of range by redisplaying the whole menu before asking again for a number. The function should return an empty string if called with an empty list.
 
For test purposes use the following four phrases in a list:
Note: This task is fashioned after the action of the [http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml Bash select statement].
fee fie
huff and puff
mirror mirror
tick tock
 
;Note:
=={{header|Ada}}==
This task is fashioned after the action of the [http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml Bash select statement].
<lang Ada>
-- menu2.adb --
-- rosetta.org menu example
-- GPS 4.3-5 (Debian)
 
=={{header|11l}}==
-- note: the use of Unbounded strings is somewhat overkill, except that
<syntaxhighlight lang="11l">V items = [‘fee fie’, ‘huff and puff’, ‘mirror mirror’, ‘tick tock’]
-- it allows Ada to handle variable length string data easily
-- ie: differing length menu items text
with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Strings.Unbounded,
Ada.Strings.Unbounded.Text_IO;
 
L
use Ada.Text_IO, Ada.Integer_Text_IO,
L(item) items
Ada.Strings.Unbounded, Ada.Strings.Unbounded.Text_IO;
print(‘#2. #.’.format(L.index + 1, item))
 
V reply = input(‘Which is from the three pigs: ’).trim(‘ ’)
procedure menu2 is
I !reply.is_digit()
package tio renames Ada.Integer_Text_IO;
L.continue
-- rename package to use a shorter name, tio, as integer get prefix
menu_item : array (1..4) of Unbounded_String;
-- 4 menu items of any length
choice : integer := 0;
-- user selection entry value
 
I Int(reply) C 1..items.len
procedure show_menu is
print(‘You chose: ’items[Int(reply) - 1])
-- display the menu options and collect the users input
L.break</syntaxhighlight>
-- into locally global variable 'choice'
begin
for pntr in menu_item'first .. menu_item'last loop
put (pntr ); put(" "); put( menu_item(pntr)); new_line;
end loop;
put("chose (0 to exit) #:"); tio.get(choice);
end show_menu;
 
{{out}}
-- main program --
<pre>
begin
1. fee fie
menu_item(1) := to_unbounded_string("Fee Fie");
2. huff and puff
menu_item(2) := to_unbounded_string("Huff & Puff");
menu_item(3). := to_unbounded_string("mirror mirror");
menu_item(4). := to_unbounded_string("tick tock");
Which is from the three pigs: a
-- setup menu selection strings in an array
1. fee fie
show_menu;
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 0
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 2
You chose: huff and puff
</pre>
 
=={{header|Action!}}==
loop
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
if choice in menu_item'range then
put("you chose #:");
case choice is
-- in a real menu, each case would execute appropriate user procedures
when 1 => put ( menu_item(choice)); new_line;
when 2 => put ( menu_item(choice)); new_line;
when 3 => put ( menu_item(choice)); new_line;
when 4 => put ( menu_item(choice)); new_line;
when others => null;
end case;
show_menu;
else
put("Menu selection out of range"); new_line;
if choice = 0 then exit; end if;
-- need a exit option !
show_menu;
end if;
end loop;
 
BYTE FUNC Init(PTR ARRAY items)
end menu2;
items(0)="fee fie"
items(1)="huff and puff"
items(2)="mirror mirror"
items(3)="tick tock"
RETURN (4)
 
PROC ShowMenu(PTR ARRAY items BYTE count)
</lang>
BYTE i
FOR i=1 TO count
DO
PrintF("(%B) %S%E",i,items(i-1))
OD
RETURN
 
BYTE FUNC GetMenuItem(PTR ARRAY items BYTE count)
<lang Ada>
BYTE res
./menu2
1 Fee Fie
DO
2 Huff & Puff
ShowMenu(items,count) PutE()
3 mirror mirror
Print("Make your choise: ")
4 tick tock
res=InputB()
chose (0 to exit) #:2
UNTIL res>=1 AND res<=count
you chose #:Huff & Puff
OD
1 Fee Fie
RETURN (res-1)
2 Huff & Puff
3 mirror mirror
4 tick tock
chose (0 to exit) #:55
Menu selection out of range
1 Fee Fie
2 Huff & Puff
3 mirror mirror
4 tick tock
chose (0 to exit) #:0
Menu selection out of range
[2010-06-09 22:18:25] process terminated successfully (elapsed time: 15.27s)
 
PROC Main()
</lang>
PTR ARRAY items(10)
BYTE count,res
 
count=Init(items)
=={{header|C}}==
res=GetMenuItem(items,count)
<lang c>#include <stdio.h>
PrintF("You have chosen: %S%E",items(res))
#include <stdlib.h>
RETURN</syntaxhighlight>
#include <string.h>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Menu.png Screenshot from Atari 8-bit computer]
<pre>
(1) fee fie
(2) huff and puff
(3) mirror mirror
(4) tick tock
 
Make your choise: 5
char *menu_select(char **items, char *prompt);
(1) fee fie
(2) huff and puff
(3) mirror mirror
(4) tick tock
 
Make your choise: 2
int
You have chosen: huff and puff
main(void)
</pre>
{
char *items[] = {"fee fie", "huff and puff", "mirror mirror", "tick tock", NULL};
char *prompt = "Which is from the three pigs?";
 
=={{header|Ada}}==
printf("You chose %s.\n", menu_select(items, prompt));
<syntaxhighlight lang="ada">with ada.text_io,Ada.Strings.Unbounded; use ada.text_io, Ada.Strings.Unbounded;
 
procedure menu is
return EXIT_SUCCESS;
type menu_strings is array (positive range <>) of Unbounded_String ;
}
function "+" (s : string) return Unbounded_String is (To_Unbounded_String (s));
 
function choice (m : menu_strings; prompt : string) return string is
char *
begin
menu_select(char **items, char *prompt)
if m'length > 0 then
{
loop
char buf[BUFSIZ];
put_line (prompt);
int i;
for i in m'range loop
int choice;
put_line (i'img &") " & To_String (m(i)));
int choice_max;
end loop;
begin
return To_String (m(positive'value (get_line)));
exception when others => put_line ("Try again !");
end;
end loop;
end if;
return "";
end choice;
 
begin
if (items == NULL)
put_line ("You chose " &
return NULL;
choice ((+"fee fie",+"huff and puff",+"mirror mirror",+"tick tock"),"Enter your choice "));
end menu;</syntaxhighlight>
 
=={{header|ALGOL 68}}==
do {
{{trans|C}}
for (i = 0; items[i] != NULL; i++) {
printf("%d) %s\n", i + 1, items[i]);
}
choice_max = i;
if (prompt != NULL)
printf("%s ", prompt);
else
printf("Choice? ");
if (fgets(buf, sizeof(buf), stdin) != NULL) {
choice = atoi(buf);
}
} while (1 > choice || choice > choice_max);
 
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
return items[choice - 1];
 
}</lang>
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''}}
<syntaxhighlight lang="algol68">PROC menu select := (FLEX[]STRING items, UNION(STRING, VOID) prompt)STRING:
(
INT choice;
IF LWB items <= UPB items THEN
WHILE
FOR i FROM LWB items TO UPB items DO
printf(($g(0)") "gl$, i, items[i]))
OD;
CASE prompt IN
(STRING prompt):printf(($g" "$, prompt)),
(VOID):printf($"Choice ? "$)
ESAC;
read((choice, new line));
# WHILE # 1 > choice OR choice > UPB items
DO SKIP OD;
items[choice]
ELSE
""
FI
);
 
test:(
FLEX[0]STRING items := ("fee fie", "huff and puff", "mirror mirror", "tick tock");
STRING prompt := "Which is from the three pigs : ";
 
printf(($"You chose "g"."l$, menu select(items, prompt)))
)</syntaxhighlight>
Output:
<pre>
Line 154 ⟶ 182:
4) tick tock
Which is from the three pigs : 2
You choosechose huff and puff.
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">menu: function [items][
selection: neg 1
while [not? in? selection 1..size items][
loop.with:'i items 'item -> print ~"|i+1|. |item|"
inp: input "Enter a number: "
if numeric? inp ->
selection: to :integer inp
]
print items\[selection-1]
]
 
menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"]</syntaxhighlight>
 
{{out}}
 
<pre>1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: something wrong
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 5
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3
mirror mirror</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang ="autohotkey">GoSub, CreateGUIMenu(list:=""){
if !list ; if called with an empty list
return
return ; return an empty string
for i, v in x := StrSplit(list, "`n", "`r")
string .= (string?"`n":"") i "- " v
, len := StrLen(v) > len ? StrLen(v) : len
while !x[Choice]
InputBox , Choice, Please Select From Menu, % string ,, % 200<len*7 ? 200 ? len*7 , % 120 + x.count()*20
return x[Choice]
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">list =
(
fee fie
huff and puff
mirror mirror
tick tock
)
MsgBox % Menu(list) ; call menu with list
MsgBox % Menu() ; call menu with empty list
return</syntaxhighlight>
 
 
Submit:
=={{header|AWK}}==
Gui, Submit, NoHide
<syntaxhighlight lang="awk">
If Input =
# syntax: GAWK -f MENU.AWK
GuiControl,,Output
BEGIN {
Else If Input not between 1 and 4
print("you picked:",menu(""))
{
print("you picked:",menu("fee fie:huff and puff:mirror mirror:tick tock"))
Gui, Destroy
exit(0)
Sleep, 500
GoSub, CreateGUI
}
function menu(str, ans,arr,i,n) {
Else {
if (str == "") {
GuiControlGet, string,,Text%Input%
return
GuiControl,,Output,% SubStr(string,4)
}
n = split(str,arr,":")
while (1) {
print("")
for (i=1; i<=n; i++) {
printf("%d - %s\n",i,arr[i])
}
printf("? ")
getline ans
if (ans in arr) {
return(arr[ans])
}
print("invalid choice")
}
}
</syntaxhighlight>
return
 
=={{header|Axe}}==
CreateGUI:
{{incorrect|Axe|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
list = fee fie,huff and puff,mirror mirror,tick tock
In Axe, static data (such as strings) is laid out sequentially in memory. So the H in "HUFF" is the byte after the null terminator for "FIE". However, null terminators are only added to strings when they are stored with the store symbol →. strGet returns a pointer to the start of the nth null-terminated string in the data, which is why the strings must be laid out in memory correctly.
Loop, Parse, list, `,
<syntaxhighlight lang="axe">"FEE FIE"→Str1
Gui, Add, Text, vText%A_Index%, %A_Index%: %A_LoopField%
"HUFF AND PUFF"→Str2
Gui, Add, Text, ym, Which is from the three pigs?
"MIRROR MIRROR"→Str3
Gui, Add, Edit, vInput gSubmit
"TICK TOCK"→Str4
Gui, Add, Edit, vOutput
For(I,1,4)
Gui, Show
Disp I▶Hex+3,":",strGet(Str1,I-1),i
return
End
 
Disp "NUMBER? "
GuiClose:
input→A
ExitApp</lang>
{A}-'0'→N
If N<1 or N>4
Disp "BAD NUMBER",i
Return
End
Disp strGet(Str1,N-1),i</syntaxhighlight>
 
=={{header|BASIC}}==
{{works with|QuickBasic|4.5}}
<langsyntaxhighlight lang="qbasic"> function sel$(choices$(), prompt$)
if ubound(choices$) - lbound(choices$) = 0 then sel$ = ""
ret$ = ""
Line 202 ⟶ 301:
while ret$ = ""
sel$ = ret$
end function</langsyntaxhighlight>
 
 
==={{header|Applesoft BASIC}}===
While the following example could be lengthened to demonstrate larger menu-driven projects, it is useful to simply print the resulting string indexed by the user input.
<syntaxhighlight lang="applessoftbasic"> 10 M$(4) = "TICK TOCK"
20 M$(3) = "MIRROR MIRROR"
30 M$(2) = "HUFF AND PUFF"
40 M$(1) = "FEE FIE"
50 GOSUB 100"MENU
60 PRINT M$
70 END
100 M$ = ""
110 FOR M = 0 TO 1 STEP 0
120 FOR N = 1 TO 1E9
130 IF LEN (M$(N)) THEN PRINT N". "M$(N): NEXT N
140 IF N = 1 THEN RETURN
150 INPUT "ENTER A NUMBER:";N%
160 M = N% > = 1 AND N% < N
170 NEXT M
180 M$ = M$(N%)
190 RETURN </syntaxhighlight>
 
==={{header|Commodore BASIC}}===
 
While the following example could be shortened to simply print the resulting string indexed by the user input, it is useful to demonstrate that larger menu-driven projects benefit from the use of the <code>ON n... GOSUB</code> statement to pass control to larger subroutines.
 
<syntaxhighlight lang="commodorebasic">1 rem menu
5 rem rosetta code
10 gosub 900
 
20 print chr$(147);chr$(14)
30 print " Menu "
35 print:print "Choose an incantation:":print
40 for i=1 to 5
45 print i;chr$(157);". ";op$(i,1)
50 next i:print
55 print "choose one: ";
60 get k$:if k$<"1" or k$>"5" then 60
65 k=val(k$):print chr$(147)
70 on k gosub 100,200,300,400,500
80 if k=5 then end
 
90 print:print "Press any key to continue."
95 get k$:if k$="" then 95
96 goto 20
 
100 rem fee fi
110 print op$(k,2)
115 return
 
200 rem huff puff
210 print op$(k,2)
215 return
 
300 rem mirror mirror
310 print op$(k,2)
315 return
 
400 rem tick tock
410 print op$(k,2)
415 return
 
500 rem quit
510 print op$(k,2):print "Goodbye!"
515 return
 
900 rem initialize
905 dim op$(10,2)
910 for a=1 to 5
915 read op$(a,1),op$(a,2)
920 next a
925 return
 
1000 data "Fee fi fo fum","I smell the blood of an Englishman!"
1005 data "Huff and puff","The house blew down!"
1010 data "Mirror, mirror","You seem to be the fairest of them all!"
1015 data "Tick tock","Time passes..."
1020 data "<Quit>","You decide to leave."</syntaxhighlight>
 
=={{header|Batch File}}==
Example 1
<syntaxhighlight lang="dos">@echo off & setlocal enabledelayedexpansion
 
set "menuChoices="fee fie","huff and puff","mirror mirror","tick tock""
 
call :menu
 
pause>nul & exit
 
 
:menu
if defined menuChoices (
set "counter=0" & for %%a in (%menuChoices%) do (
set /a "counter+=1"
set "currentMenuChoice=%%a"
set option[!counter!]=!currentMenuChoice:"=!
)
)
:tryagain
cls&echo.
for /l %%a in (1,1,%counter%) do echo %%a^) !option[%%a]!
echo.
set /p "input=Choice 1-%counter%: "
echo.
for /l %%a in (1,1,%counter%) do (
if !input! equ %%a echo You chose [ %%a^) !option[%%a]! ] & goto :EOF
)
echo.
echo.Invalid Input. Please try again...
pause
goto :tryagain</syntaxhighlight>
Example 2
<syntaxhighlight lang="dos">
@echo off
 
call:menu "fee fie" "huff and puff" "mirror mirror" "tick tock"
pause>nul
exit /b
 
:menu
cls
setlocal enabledelayedexpansion
set count=0
set reset=endlocal ^& goto menu
:menuloop
for %%i in (%*) do (
set /a count+=1
set string[!count!]=%%~i
echo string[!count!] = %%~i
)
echo.
set /p choice=^>
if "%choice%"=="" %reset%
set "isNum="
for /f "delims=0123456789" %%i in ("%choice%") do set isNum=%%i
if defined isNum %reset%
if %choice% gtr %count% %reset%
echo.!string[%choice%]!
goto:eof
</syntaxhighlight>
 
=={{header|BBC BASIC}}==
<syntaxhighlight lang="bbcbasic"> DIM list$(4)
list$() = "fee fie", "huff and puff", "mirror mirror", "tick tock"
selected$ = FNmenu(list$(), "Please make a selection: ")
PRINT selected$
END
DEF FNmenu(list$(), prompt$)
LOCAL index%, select$
IF SUM(list$()) = "" THEN = ""
REPEAT
CLS
FOR index% = 0 TO DIM(list$() ,1)
IF list$(index%)<>"" PRINT ; index% ":", list$(index%)
NEXT
PRINT prompt$ ;
INPUT "" select$
index% = VAL(select$)
IF select$<>STR$(index%) index% = -1
IF index%>=0 IF index%<=DIM(list$() ,1) IF list$(index%)="" index% = -1
UNTIL index%>=0 AND index%<=DIM(list$(), 1)
= list$(index%)</syntaxhighlight>
Empty entries in the list are not offered as options, nor accepted as a selection.
 
=={{header|Brat}}==
<syntaxhighlight lang="brat">menu = { prompt, choices |
true? choices.empty?
{ "" }
{
choices.each_with_index { c, i |
p "#{i}. #{c}"
}
 
selection = ask prompt
 
true? selection.numeric?
{ selection = selection.to_i
true? selection < 0 || { selection >= choices.length }
{ p "Selection is out of range"; menu prompt, choices }
{ choices[selection] }
}
{ p "Selection must be a number"; menu prompt, choices }
}
}
 
p menu "Selection: " ["fee fie" "huff and puff" "mirror mirror" "tick tock"]</syntaxhighlight>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
const char *menu_select(const char *const *items, const char *prompt);
 
int
main(void)
{
const char *items[] = {"fee fie", "huff and puff", "mirror mirror", "tick tock", NULL};
const char *prompt = "Which is from the three pigs?";
 
printf("You chose %s.\n", menu_select(items, prompt));
Line 221 ⟶ 508:
}
 
const char *
menu_select(const char *const *items, const char *prompt)
{
char buf[BUFSIZ];
Line 247 ⟶ 534:
 
return items[choice - 1];
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">
using System;
using System.Collections.Generic;
 
public class Menu
{
static void Main(string[] args)
{
List<string> menu_items = new List<string>() { "fee fie", "huff and puff", "mirror mirror", "tick tock" };
//List<string> menu_items = new List<string>();
Console.WriteLine(PrintMenu(menu_items));
Console.ReadLine();
}
private static string PrintMenu(List<string> items)
{
if (items.Count == 0)
return "";
 
string input = "";
int i = -1;
do
{
for (int j = 0; j < items.Count; j++)
Console.WriteLine("{0}) {1}", j, items[j]);
 
Console.WriteLine("What number?");
input = Console.ReadLine();
 
} while (!int.TryParse(input, out i) || i >= items.Count || i < 0);
return items[i];
}
}
</syntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <boost/regex.hpp>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
 
void printMenuprint_menu(const std::vector<std::string>& *, intterms);
{
//checks whether entered data is in required range
for (size_t i = 0; i < terms.size(); i++) {
bool checkEntry(string, const string *, int);
std::cout << i + 1 << ") " << terms[i] << '\n';
}
string dataEntry(string prompt, const string *terms, int size) {
if (size == 0) { //we return an empty string when we call the function with an empty list
return "";
}
string entry;
do {
printMenu(terms, size);
cout << prompt;
cin >> entry;
}
while( !checkEntry(entry, terms, size) );
int number = atoi(entry.c_str());
return terms[number - 1];
}
 
voidint printMenuparse_entry(const std::string& *termsentry, int nummax_number) {
{
for (int i = 1 ; i < num + 1 ; i++) {
int number = std::stoi(entry);
cout << i << ')' << terms[ i - 1 ] << '\n';
if (number < 1 || number > max_number) {
}
throw std::invalid_argument("");
}
 
return number;
}
 
boolstd::string checkEntrydata_entry(const std::string& myEntryprompt, const std::vector<std::string>& *terms, int num) {
{
boost::regex e("^\\d+$");
if (!boost::regex_matchterms.empty(myEntry, e)) {
return false"";
}
int number = atoi(myEntry.c_str());
 
if (number < 1 || number > num)
int return falsechoice;
return while (true;) {
print_menu(terms);
std::cout << prompt;
 
std::string entry;
std::cin >> entry;
 
try {
choice = parse_entry(entry, terms.size());
return terms[choice - 1];
} catch (std::invalid_argument&) {
// std::cout << "Not a valid menu entry!" << std::endl;
}
}
}
 
int main( ) {
{
const string terms[ ] = { "fee fie" , "huff and puff" , "mirror mirror" , "tick tock" };
std::vector<std::string> terms = {"fee fie", "huff and puff", "mirror mirror", "tick tock"};
int size = sizeof terms / sizeof *terms;
std::cout << "You chose: " << dataEntrydata_entry("Which is from the three pigs:> ", terms, size) << std::endl;
}
return 0;
</syntaxhighlight>
}</lang>
 
=={{header|Ceylon}}==
<syntaxhighlight lang="ceylon">"Run the module `menu`."
shared void run() {
value selection = menu("fee fie", "huff And puff", "mirror mirror", "tick tock");
print(selection);
}
 
String menu(String* strings) {
if(strings.empty) {
return "";
}
value entries = map(zipEntries(1..strings.size, strings));
while(true) {
for(index->string in entries) {
print("``index``) ``string``");
}
process.write("> ");
value input = process.readLine();
if(exists input, exists int = parseInteger(input), exists string = entries[int]) {
return string;
}
}
}
 
</syntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn menu [prompt choices]
(if (empty? choices)
""
Line 323 ⟶ 671:
(println "You chose: "
(menu "Which is from the three pigs: "
["fee fie" "huff and puff" "mirror mirror" "tick tock"]))</langsyntaxhighlight>
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. Test-Prompt-Menu.
 
DATA DIVISION.
WORKING-STORAGE SECTION.
 
01 Num-Options USAGE UNSIGNED-INT VALUE 4.
01 Example-Menu.
03 Example-Options-Data.
05 FILLER PIC X(30) VALUE "fee fie".
05 FILLER PIC X(30) VALUE "huff and puff".
05 FILLER PIC X(30) VALUE "mirror mirror".
05 FILLER PIC X(30) VALUE "tick tock".
 
03 Example-Options-Values REDEFINES Example-Options-Data.
05 Example-Options PIC X(30) OCCURS 4 TIMES.
 
01 Chosen-Option PIC X(30).
 
PROCEDURE DIVISION.
CALL "Prompt-Menu" USING BY CONTENT Num-Options
BY CONTENT Example-Menu
BY REFERENCE Chosen-Option
 
DISPLAY "You chose: " Chosen-Option
 
GOBACK
.
 
END PROGRAM Test-Prompt-Menu.
 
IDENTIFICATION DIVISION.
PROGRAM-ID. Prompt-Menu.
 
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 User-Input USAGE UNSIGNED-INT.
01 Input-Flag PIC X.
88 Valid-Input VALUE "Y".
 
01 Options-Index USAGE UNSIGNED-INT.
01 Index-Display PIC Z(10).
 
LINKAGE SECTION.
 
01 Num-Options USAGE UNSIGNED-INT.
01 Menu-Options.
03 Options-Table PIC X(30) OCCURS 0 TO 10000000 TIMES
DEPENDING ON Num-Options.
 
01 Chosen-Option PIC X(30).
 
PROCEDURE DIVISION USING Num-Options Menu-Options Chosen-Option.
Main.
IF Num-Options = 0
MOVE SPACES TO Chosen-Option
GOBACK
END-IF
 
PERFORM UNTIL Valid-Input
PERFORM Display-Menu-Options
 
DISPLAY "Choose an option: " WITH NO ADVANCING
ACCEPT User-Input
 
PERFORM Validate-Input
END-PERFORM
 
MOVE Options-Table (User-Input) TO Chosen-Option
 
GOBACK
.
 
Display-Menu-Options.
PERFORM VARYING Options-Index FROM 1 BY 1
UNTIL Num-Options < Options-Index
MOVE Options-Index TO Index-Display
DISPLAY
Index-Display ". " Options-Table (Options-Index)
END-DISPLAY
END-PERFORM
.
 
Validate-Input.
IF User-Input = 0 OR > Num-Options
DISPLAY "Invalid input."
ELSE
SET Valid-Input TO TRUE
END-IF
.
 
END PROGRAM Prompt-Menu.</syntaxhighlight>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun select (prompt choices)
(if (null choices)
""
Line 338 ⟶ 780:
(force-output)
(setf n (parse-integer (read-line *standard-input* nil)
:junk-allowed t)))))</langsyntaxhighlight>
 
=={{header|D}}==
<syntaxhighlight lang="d">
<lang d>import std.stdio;
import std.stdio, std.conv, std.string, std.array, std.typecons;
 
import std.string;
string menuSelect(in string[] entries) {
void main() {
static Nullable!(int, -1) validChoice(in string input,
char[][]items = ["fee fie","huff and puff","mirror mirror","tick tock"];
in int nEntries)
writefln("You chose %s",doSelect(items));
pure nothrow {
try {
immutable n = input.to!int;
 
return typeof(return)((n >= 0 && n <= nEntries) ? n : -1);
} catch (Exception e) // Very generic
return typeof(return)(-1); // Not valid.
}
 
if (entries.empty)
return "";
 
while (true) {
"Choose one:".writeln;
foreach (immutable i, const entry; entries)
writefln(" %d) %s", i, entry);
"> ".write;
 
immutable input = readln.chomp;
 
immutable choice = validChoice(input, cast(int) (entries.length - 1));
 
if (choice.isNull)
"Wrong choice.".writeln;
else
return entries[choice]; // We have a valid choice.
}
}
 
void main() {
char[]doSelect(char[][]input) {
immutable items = ["fee fie", "huff and puff",
if (!input.length) return "";
"mirror mirror", "tick tock"];
char[]line;
 
int choice;
writeln("You chose '", items.menuSelect, "'.");
do {
writefln("Choose one:");
foreach(i,item;input) {
writefln("%d) %s",i,item);
}
writef("> ");
line = readln();
line = chomp(line);
choice = ValidChoice(input.length-1,line);
} while (choice == -1);
// we have a valid choice
return input[choice];
}
</syntaxhighlight>
 
{{out}}
int ValidChoice(int max,char[]input) {
<pre>
int tmp;
Choose one:
try tmp = toInt(input);
0) fee fie
catch(Error e) return -1;
1) huff and puff
if (tmp <= max && tmp >= 0) {
2) mirror mirror
return tmp;
3) tick }tock
> 2
return -1;
You chose 'mirror mirror'.
}</lang>
</pre>
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Menu;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
function ChooseMenu(Options: TArray<string>; Prompt: string): string;
var
index: Integer;
value: string;
begin
if Length(Options) = 0 then
exit('');
repeat
writeln;
for var i := 0 to length(Options) - 1 do
writeln(i + 1, '. ', Options[i]);
write(#10, Prompt, ' ');
Readln(value);
index := StrToIntDef(value, -1);
until (index > 0) and (index <= length(Options));
Result := Options[index];
end;
 
begin
writeln('You picked ', ChooseMenu(['fee fie', 'huff and puff', 'mirror mirror',
'tick tock'], 'Enter number: '));
readln;
end.</syntaxhighlight>
{{out}}
<pre>
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
 
Enter number: 5
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
 
Enter number: 2
You picked huff and puff</pre>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Menu do
def select(_, []), do: ""
def select(prompt, items) do
IO.puts ""
Enum.with_index(items) |> Enum.each(fn {item,i} -> IO.puts " #{i}. #{item}" end)
answer = IO.gets("#{prompt}: ") |> String.strip
case Integer.parse(answer) do
{num, ""} when num in 0..length(items)-1 -> Enum.at(items, num)
_ -> select(prompt, items)
end
end
end
 
# test empty list
response = Menu.select("Which is empty", [])
IO.puts "empty list returns: #{inspect response}"
# "real" test
items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
response = Menu.select("Which is from the three pigs", items)
IO.puts "you chose: #{inspect response}"</syntaxhighlight>
 
{{out}}
<pre>
empty list returns: ""
 
0. fee fie
1. huff and puff
2. mirror mirror
3. tick tock
Which is from the three pigs: 4
 
0. fee fie
1. huff and puff
2. mirror mirror
3. tick tock
Which is from the three pigs: 3
you chose: "tick tock"
</pre>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">
 
(let ((prompt-buffer-name "***** prompt *****")
(option-list '("fee fie"
"huff and puff"
"mirror mirror"
"tick tock"))
(extra-prompt-message "")
(is-selected nil)
(user-input-value nil))
 
;; Switch to an empty buffer
(switch-to-buffer-other-window prompt-buffer-name)
(read-only-mode -1)
(erase-buffer)
;; Display the options
(cl-loop for opt-idx from 1 to (length option-list) do
(insert (format "%d\) %s \n" opt-idx (nth (1- opt-idx) option-list))))
(while (not is-selected)
;; Read user input
(setq user-input-value (read-string (concat "select an option" extra-prompt-message " : ")))
(setq user-input-value (read user-input-value))
;; Validate user input
(if (and (fixnump user-input-value)
(<= user-input-value (length option-list))
(> user-input-value 0))
;; Display result
(progn
(end-of-buffer)
(insert (concat "\nYou selected: " (nth (1- user-input-value) option-list)))
(setq is-selected 't)
)
(progn
(setq extra-prompt-message " (please input a valid number)")
)
)
)
)
 
</syntaxhighlight>
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROCEDURE Selection(choices$[],prompt$->sel$)
IF UBOUND(choices$,1)-LBOUND(choices$,1)=0 THEN
sel$=""
EXIT PROCEDURE
END IF
ret$=""
REPEAT
FOR i=LBOUND(choices$,1) TO UBOUND(choices$,1) DO
PRINT(i;": ";choices$[i])
END FOR
PRINT(prompt$;)
INPUT(index)
IF index<=UBOUND(choices$,1) AND index>=LBOUND(choices$,1) THEN ret$=choices$[index] END IF
UNTIL ret$<>""
sel$=ret$
END PROCEDURE
</syntaxhighlight>
 
=={{header|Euphoria}}==
<syntaxhighlight lang="euphoria">include get.e
 
function menu_select(sequence items, object prompt)
if length(items) = 0 then
return ""
else
for i = 1 to length(items) do
printf(1,"%d) %s\n",{i,items[i]})
end for
if atom(prompt) then
prompt = "Choice?"
end if
return items[prompt_number(prompt,{1,length(items)})]
end if
end function
 
constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"}
constant prompt = "Which is from the three pigs? "
 
printf(1,"You chose %s.\n",{menu_select(items,prompt)})</syntaxhighlight>
 
=={{header|F Sharp|F#}}==
<syntaxhighlight lang="fsharp">open System
 
let rec menuChoice (options : string list) prompt =
if options = [] then ""
else
for i = 0 to options.Length - 1 do
printfn "%d. %s" (i + 1) options.[i]
 
printf "%s" prompt
let input = Int32.TryParse(Console.ReadLine())
 
match input with
| true, x when 1 <= x && x <= options.Length -> options.[x - 1]
| _, _ -> menuChoice options prompt
 
[<EntryPoint>]
let main _ =
let menuOptions = ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"]
let choice = menuChoice menuOptions "Choose one: "
printfn "You chose: %s" choice
 
0</syntaxhighlight>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USEUSING: formatting io kernel math math.parser sequences ;
 
: print-menu ( seq -- )
Line 384 ⟶ 1,047:
"Your choice? " write flush ;
 
: (select) ( seq -- result )
dup print-menu readln string>number dup integer? [
drop 1 - swap 2dup bounds-check?
readln string>number [
1[ -nth swap] 2dup[ bounds-check?nip (select) ] if
[ nth ] [ nipdrop (select) ] if* ;
 
] [ select ] if* ;</lang>
: select ( seq -- result ) [ "" ] [ (select) ] if-empty ;</syntaxhighlight>
 
Example usage:
Line 401 ⟶ 1,065:
--- Data stack:
"fee fie"</pre>
 
=={{header|Fantom}}==
{{incorrect|Fantom|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<syntaxhighlight lang="fantom">class Main
{
static Void displayList (Str[] items)
{
items.each |Str item, Int index|
{
echo ("$index: $item")
}
}
 
public static Str getChoice (Str[] items)
{
selection := -1
while (selection == -1)
{
displayList (items)
Env.cur.out.print ("Select: ").flush
input := Int.fromStr(Env.cur.in.readLine, 10, false)
if (input != null)
{
if (input >= 0 && input < items.size)
{
selection = input
}
}
echo ("Try again")
}
return items[selection]
}
 
public static Void main ()
{
choice := getChoice (["fee fie", "huff and puff", "mirror mirror", "tick tock"])
echo ("You chose: $choice")
}
}</syntaxhighlight>
 
=={{header|Forth}}==
===Idiomatic Forth===
Out of the box Forth does not have lists. This version uses strings and a vector table, which arguably is more how one would do this task in Forth. It returns a nil string if a nil string is given otherwise the input string becomes the title of the menu.
<syntaxhighlight lang="forth">\ Rosetta Code Menu Idiomatic Forth
 
\ vector table compiler
: CASE: ( -- ) CREATE ;
: | ( -- <text>) ' , ; IMMEDIATE
: ;CASE ( -- ) DOES> SWAP CELLS + @ EXECUTE ;
 
: NIL ( -- addr len) S" " ;
: FEE ( -- addr len) S" fee fie" ;
: HUFF ( -- addr len) S" huff and puff" ;
: MIRROR ( -- addr len) S" mirror mirror" ;
: TICKTOCK ( -- addr len) S" tick tock" ;
 
CASE: SELECT ( n -- addr len)
| NIL | FEE | HUFF | MIRROR | TICKTOCK
;CASE
 
CHAR 1 CONSTANT '1'
CHAR 4 CONSTANT '4'
: BETWEEN ( n low hi -- ?) 1+ WITHIN ;
 
: MENU ( addr len -- addr len )
DUP 0=
IF
2DROP NIL EXIT
ELSE
BEGIN
CR
CR 2DUP 3 SPACES TYPE
CR ." 1 " 1 SELECT TYPE
CR ." 2 " 2 SELECT TYPE
CR ." 3 " 3 SELECT TYPE
CR ." 4 " 4 SELECT TYPE
CR ." Choice: " KEY DUP EMIT
DUP '1' '4' BETWEEN 0=
WHILE
DROP
REPEAT
-ROT 2DROP \ drop input string
CR [CHAR] 0 - SELECT
THEN
;</syntaxhighlight>
 
===If there must be lists===
Here we extend Forth to support simple lists and complete the task using the language extensions.
<syntaxhighlight lang="forth">\ Rosetta Menu task with Simple lists in Forth
 
: STRING, ( caddr len -- ) HERE OVER CHAR+ ALLOT PLACE ;
: " ( -- ) [CHAR] " PARSE STRING, ;
 
: { ( -- ) ALIGN 0 C, ;
: } ( -- ) { ;
 
: {NEXT} ( str -- next_str) COUNT + ;
: {NTH} ( n array_addr -- str) SWAP 0 DO {NEXT} LOOP ;
 
: {LEN} ( array_addr -- ) \ count strings in a list
0 >R \ Counter on Rstack
{NEXT} \ skip 1st empty string
BEGIN
{NEXT} DUP C@ \ Fetch length byte
WHILE \ While true
R> 1+ >R \ Inc. counter
REPEAT
DROP
R> ; \ return counter to data stack
 
: {TYPE} ( $ -- ) COUNT TYPE ;
: '"' ( -- ) [CHAR] " EMIT ;
: {""} ( $ -- ) '"' SPACE {TYPE} '"' SPACE ;
: }PRINT ( n array -- ) {NTH} {TYPE} ;
 
\ ===== TASK BEGINS =====
CREATE GOODLIST
{ " fee fie"
" huff and puff"
" mirror mirror"
" tick tock" }
 
CREATE NIL { }
 
CHAR 1 CONSTANT '1'
CHAR 4 CONSTANT '4'
CHAR 0 CONSTANT '0'
 
: BETWEEN ( n low hi -- ?) 1+ WITHIN ;
 
: .MENULN ( n -- n) DUP '0' + EMIT SPACE OVER }PRINT ;
 
: MENU ( list -- string )
DUP {LEN} 0=
IF
DROP NIL
ELSE
BEGIN
CR
CR 1 .MENULN
CR 2 .MENULN
CR 3 .MENULN
CR 4 .MENULN
CR ." Choice: " KEY DUP EMIT
DUP '1' '4' BETWEEN
0= WHILE
DROP
REPEAT
[CHAR] 0 -
CR SWAP {NTH}
THEN
;</syntaxhighlight>
 
Test at the gForth console
<PRE>GOODLIST MENU
 
1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: 0
 
1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: Q
 
1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: 2
ok
{TYPE} huff and puff ok
ok
NIL MENU ok
{TYPE} ok</PRE>
 
=={{header|Fortran}}==
 
Please find the build instructions in the comments at the start of the FORTRAN 2008 source. Compiler: gfortran from the GNU compiler collection. Command interpreter: bash.
<syntaxhighlight lang="fortran">
!a=./f && make $a && OMP_NUM_THREADS=2 $a
!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f
 
module menu
public :: selector
contains
 
function selector(title,options) result(choice)
character(len=*),intent(in) :: title
character(len=*),dimension(:),intent(in) :: options
character(len=len(options)) :: choice
integer :: i,ichoose,ios,n
 
choice = ""
 
n = size(options)
if (n > 0) then
do
print "(a)",title
print "(i8,"", "",a)",(i,options(i),i=1,n)
read (*,fmt="(i8)",iostat=ios) ichoose
 
if (ios == -1) exit ! EOF error
if (ios /= 0) cycle ! other error
if (ichoose < 1) cycle
if (ichoose > n) cycle ! out-of-bounds
 
choice = options(ichoose)
exit
end do
end if
end function selector
end module menu
 
program menu_demo
use menu
character(len=14),dimension(:),allocatable :: zero_items,fairytale
character(len=len(zero_items)) :: s
 
!! empty list demo
allocate(zero_items(0))
print "(a)","input items:",zero_items
s = selector('Choose from the empty list',zero_items)
print "(a)","returned:",s
if (s == "") print "(a)","(an empty string)"
 
!! Fairy tale demo
allocate(fairytale(4))
fairytale = (/'fee fie ','huff and puff ', &
'mirror mirror ','tick tock '/)
print "(a)","input items:",fairytale
s = selector('Choose a fairy tale',fairytale)
print "(a)","returned: ",s
if (s == "") print "(a)","(an empty string)"
 
end program menu_demo
 
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">dim as string menu(1 to 4)={ "fee fie", "huff and puff", "mirror mirror", "tick tock" }
 
function menu_select( m() as string ) as string
dim as integer i, vc = 0
dim as string c
while vc<1 or vc > ubound(m)
cls
for i = 1 to ubound(m)
print i;" ";m(i)
next i
print
input "Choice? ", c
vc = val(c)
wend
return m(vc)
end function
 
print menu_select( menu() )</syntaxhighlight>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_window = 1
begin enum 1
_response
_popupBtn
end enum
 
void local fn BuildPopUpMenu
menu 101
menu 101, 0,, @"Select numbered menu item from the Three Pigs"
menu 101, 1,, @"1. fee fie"
menu 101, 2,, @"2. huff and puff"
menu 101, 3,, @"3. mirror mirror"
menu 101, 4,, @"4. tick tock"
menu 101, 5,, @" ?????????"
end fn
 
void local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 480, 360 )
window _window, @"Rosetta Code Menu Task", r, NSWindowStyleMaskTitled + NSWindowStyleMaskClosable + NSWindowStyleMaskMiniaturizable
r = fn CGRectMake( 45, 240, 380, 34 )
textlabel _response,, r, _window
ControlSetAlignment( _response, NSTextAlignmentCenter )
r = fn CGRectMake( 65, 200, 340, 34 )
popupbutton _popupBtn,,,, r, YES
PopUpButtonSetMenu( _popupBtn, 101 )
end fn
 
void local fn DoMenu( menuID as long, itemID as long )
select (menuID)
select (ItemID)
case 1 : ControlSetStringValue( _response, @"1. Sorry, wrong: From Jack the Giant Killer." )
case 2 : ControlSetStringValue( _response, @"2. CORRECT!: From The Three Little Pigs." )
case 3 : ControlSetStringValue( _response, @"3. Sorry, wrong: From Snow White and the Seven Dwarfs." )
case 4 : ControlSetStringValue( _response, @"4. Sorry, wrong: From Tick Tock Goes the Clock Rhyme." )
case 5 : ControlSetStringValue( _response, @"Surely you could just make a guess! Try again." )
end select
end select
end fn
 
fn BuildPopUpMenu
fn BuildWindow
 
on menu fn DoMenu
 
HandleEvents
</syntaxhighlight>
[[file:Rosetta_Code_FutureBasic_Menu_Task.png]]
 
 
=={{header|Gambas}}==
<syntaxhighlight lang="gambas">
Public Sub Main()
 
Dim asMenu As String[] = ["fee fie", "huff And puff", "mirror mirror", "tick tock"]
Dim sValuePrompt As String = "Please select one of the above numbers> "
Dim sChoice As String
Dim sFeedbackFormat As String = "You have chosen '&1'\r\n"
 
sChoice = Menu(asMenu, sValuePrompt)
If sChoice = "" Then
Print "menu returned an empty string"
Else
Print Subst(sFeedbackFormat, sChoice)
Endif
 
End
 
Private Function Menu(asChoices As String[], sPrompt As String) As String
 
Dim sReturnValue As String = ""
Dim sMenuLineFormat As String = "&1) &2"
Dim sAnswer As String
Dim iAnswer As Integer
Dim iIndex As Integer = 0
Dim sMenuItem As String
 
If Not IsNull(asChoices) Then
If asChoices.Count > 0 Then
Do
For iIndex = 0 To asChoices.Max
sMenuItem = asChoices[iIndex]
Print Subst(sMenuLineFormat, iIndex, sMenuItem)
Next
 
Print sPrompt
Input sAnswer
 
If IsNumber(sAnswer) Then
iAnswer = sAnswer
If (0 <= iAnswer) And (iAnswer <= asChoices.Max) Then
sReturnValue = asChoices[iAnswer]
Break
Endif
Endif
Loop
Endif
Endif
 
Return sReturnValue
 
End
</syntaxhighlight>
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import "fmt"
 
func menu(choices []string, prompt string) string {
if len(choices) == 0 {
return ""
}
var c int
for {
fmt.Println("")
for i, s := range choices {
fmt.Printf("%d. %s\n", i+1, s)
}
fmt.Print(prompt)
_, err := fmt.Scanln(&c)
 
if err == nil && c > 0 && c <= len(choices) {
break
}
}
return choices[c-1]
}
 
func main() {
pick := menu(nil, "No prompt")
fmt.Printf("No choices, result = %q\n", pick)
 
choices := []string{
"fee fie",
"huff and puff",
"mirror mirror",
"tick tock",
}
pick = menu(choices, "Enter number: ")
fmt.Printf("You picked %q\n", pick)
}</syntaxhighlight>
Output:
<pre>
No choices, result = ""
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter number: 2
You picked "huff and puff"
</pre>
 
=={{header|GW-BASIC}}==
<syntaxhighlight lang="gwbasic">
10 DATA "Fee fie", "Huff and Puff", "Mirror mirror", "Tick tock"
20 VC = 0
30 DIM M$(3)
40 FOR I = 0 TO 3
50 READ M$(I)
60 NEXT I
70 CLS
80 FOR I = 0 TO 3
90 PRINT I+1;" ";M$(I)
100 NEXT I
110 PRINT
120 INPUT "Choice? ", C$
130 VC = VAL(C$)
140 IF VC<1 OR VC>4 THEN GOTO 70
150 PRINT "You picked ", M$(VC-1)
160 END
</syntaxhighlight>
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">module RosettaSelect where
 
import Data.Maybe (listToMaybe)
Line 426 ⟶ 1,529:
 
maybeRead :: Read a => String -> Maybe a
maybeRead = fmap fst . listToMaybe . filter (null . snd) . reads</langsyntaxhighlight>
 
Example usage, at the GHCI prompt:
<langsyntaxhighlight Haskelllang="haskell">*RosettaSelect> select ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
1) fee fie
2) huff and puff
Line 436 ⟶ 1,539:
Choose an item: 3
"mirror mirror"
*RosettaSelect></langsyntaxhighlight>
 
=={{header|HicEst}}==
== Icon and Unicon ==
{{incorrect|HicEst|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
==={{header|Icon}}===
<syntaxhighlight lang="hicest">CHARACTER list = "fee fie,huff and puff,mirror mirror,tick tock,", answer*20
<lang Icon>procedure main()
 
POP(Menu=list, SelTxt=answer)
 
SUBROUTINE list ! callback procedure must have same name as menu argument
! Subroutine with no arguments: all objects are global
! The global variable $$ returns the selected list index
WRITE(Messagebox, Name) answer, $$
END</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
New version :
Note the procedures below the "subroutines below" line are the actual
Rosetta task set.
 
procedure main() shows how to call the choose_from_menu "function", which demonstrates use of differing menu lists and a empty list.
 
<syntaxhighlight lang="icon">
## menu.icn : rewrite of the faulty version on Rosetta Code site 24/4/2021
 
procedure main()
L := ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
K := ["hidie hi", "hidie ho", "mirror mirror on the Wall", "tick tock tick tok"]
Z := []
choice := choose_from_menu(L) # call using menu L
write("Returned value =", choice)
choice := choose_from_menu(K) # call using menu K
write("Returned value =", choice)
choice := choose_from_menu(Z) # call using empty list
write("Returned value =", choice)
 
every i := 1 to *L do
end ## of main
write(i,") ",L[i])
# --------- subroutines below ---------------------------------
 
procedure choose_from_menu(X)
displaymenu(X)
repeat {
writes("Choose a number from the menu above: ")
a := read()
if 1a <== integer"" then return(a) <= i then## no breakselection
write("You selected ",a)
if numeric(a) then {
if integer(a) <= 0 | integer(a) > *X then displaymenu(X) else
{ ## check entered option in range
write(a, " ==> ",X[a])
return ( string(a))
}
}
else displaymenu(X)
}
 
write("You selected ",a," ==> ",L[a])
end ## choose_from_menu(X)
end</lang>
 
==={{header|Unicon}}===
procedure displaymenu(X)
This Icon solution works in Unicon.
every i := 1 to *X do
write(i,") ",X[i]) ## dispay menu options
end ## displaymenu(X)
 
</syntaxhighlight>
 
=={{header|J}}==
 
'''Solution:'''
<syntaxhighlight lang="j">
<lang j>require'misc'
CHOICES =: ];._2 'fee fie;huff and puff;mirror mirror;tick tock;'
showMenu =: i.@# smoutput@,&":&> ' '&,&.>
makeMsg PROMPT =: 'ChooseWhich ais numberfrom 0..'the ,three ':pigs? ',~ ":@<:@#
errorMsg =: [ smoutput bind 'Please choose a valid number!'
select=: ({::~ _&".@prompt@(makeMsg [ showMenu)) :: ($:@errorMsg)</lang>
See [[Talk:Select#J_implementation|Talk page]] for explanation of code.
 
showMenu =: smoutput@:(,"1~ (' ' ,.~ 3 ": i.@:(1 ,~ #)))
'''Example use:'''
read_stdin =: 1!:1@:1:
<lang j> select 'fee fie'; 'huff and puff'; 'mirror mirror'; 'tick tock'</lang>
 
menu =: '? '&$: :(4 : 0)
This would display:
NB. use: [prompt] menu choice_array
CHOICES =. y
if. 0 = # CHOICES do. return. end.
PROMPT =. x
whilst. RESULT -.@:e. i. # CHOICES do.
showMenu CHOICES
smoutput PROMPT
RESULT =. _1 ". read_stdin''
end.
RESULT {:: CHOICES
)
</syntaxhighlight>
 
See [[Talk:Select#J_implementation|Talk page]] for explanation.
0 fee fie
1 huff and puff
2 mirror mirror
3 tick tock
choose a number 0..3:
 
And, if the user responded with 2, would return: <tt>mirror mirror</tt>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java5">public static String select(List<String> list, String prompt){
if(list.size() == 0) return "";
Scanner sc = new Scanner(System.in);
Line 495 ⟶ 1,651:
}while(ret == null);
return ret;
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{works with|JScriptNode.js}} for the I/O.
<syntaxhighlight lang="javascript">const readline = require('readline');
<lang javascript>function select(question, choices) {
var prompt = "";
for (var i in choices)
prompt += i + ". " + choices[i] + "\n";
prompt += question;
 
async function menuSelect(question, choices) {
var input;
if (choices.length === 0) return '';
while (1) {
 
WScript.Echo(prompt);
const prompt = choices.reduce((promptPart, choice, i) => {
input = parseInt( WScript.StdIn.readLine() );
return promptPart += `${i + 1}. ${choice}\n`;
if (0 <= input && input < choices.length)
}, '');
break;
 
WScript.Echo("\nTry again.");
let inputChoice = -1;
while (inputChoice < 1 || inputChoice > choices.length) {
inputChoice = await getSelection(`\n${prompt}${question}: `);
}
 
return choices[inputChoice - 1];
}
 
function getSelection(prompt) {
return new Promise((resolve) => {
const lr = readline.createInterface({
input: process.stdin,
output: process.stdout
});
 
lr.question(prompt, (response) => {
lr.close();
resolve(parseInt(response) || -1);
});
});
}
 
const choices = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock'];
const question = 'Which is from the three pigs?';
menuSelect(question, choices).then((answer) => {
console.log(`\nYou chose ${answer}`);
});</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq|1.5}}
This version uses jq 1.5's 'input' builtin to read programmatically from STDIN.
<syntaxhighlight lang="jq">def choice:
def read(prompt; max):
def __read__:
prompt,
( input as $input
| if ($input|type) == "number" and 0 < $input and $input <= max then $input
else __read__
end);
__read__;
if length == 0 then ""
else
. as $in
| ("Enter your choice:\n" +
(reduce range(0; length) as $i (""; . + "\($i + 1): \($in[$i])\n")) ) as $prompt
| read($prompt; length) as $read
| if ($read|type) == "string" then $read
else "Thank you for selecting \($in[$read-1])" end
end ;</syntaxhighlight>
'''Example:'''
<syntaxhighlight lang="jq">["fee fie", "huff and puff", "mirror mirror", "tick tock"] | choice</syntaxhighlight>
<syntaxhighlight lang="sh">
$ jq -n -r -f Menu.jq
Enter your choice:
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
5
Enter your choice:
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
1
Thank you for selecting fee fie</syntaxhighlight>
 
=={{header|Julia}}==
{{trans|Python}}
 
<syntaxhighlight lang="julia">using Printf
 
function _menu(items)
for (ind, item) in enumerate(items)
@printf " %2i) %s\n" ind item
end
end
 
_ok(::Any,::Any) = false
function _ok(reply::AbstractString, itemcount)
n = tryparse(Int, reply)
return isnull(n) || 0 ≤ get(n) ≤ itemcount
end
 
"Prompt to select an item from the items"
function _selector(items, prompt::AbstractString)
isempty(items) && return ""
reply = -1
itemcount = length(items)
while !_ok(reply, itemcount)
_menu(items)
print(prompt)
reply = strip(readline(STDIN))
end
return items[parse(Int, reply)]
end
 
items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
item = _selector(items, "Which is from the three pigs: ")
println("You chose: ", item)</syntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
fun menu(list: List<String>): String {
if (list.isEmpty()) return ""
val n = list.size
while (true) {
println("\n M E N U\n")
for (i in 0 until n) println("${i + 1}: ${list[i]}")
print("\nEnter your choice 1 - $n : ")
val index = readLine()!!.toIntOrNull()
if (index == null || index !in 1..n) continue
return list[index - 1]
}
return input;
}
 
fun main(args: Array<String>) {
var choices = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock'];
val list = listOf(
var choice = select("Which is from the three pigs?", choices);
"fee fie",
WScript.Echo("you selected: " + choice + " -> " + choices[choice]);</lang>
"huff and puff",
"mirror mirror",
"tick tock"
)
val choice = menu(list)
println("\nYou chose : $choice")
}</syntaxhighlight>
Sample session:
{{out}}
<pre>
M E N U
 
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
Enter your choice 1 - 4 : 0
 
M E N U
 
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
Enter your choice 1 - 4 : asdf
 
M E N U
 
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
Enter your choice 1 - 4 : 2
 
You chose : huff and puff
</pre>
 
=={{header|langur}}==
<syntaxhighlight lang="langur">val .select = impure fn(.entries) {
if .entries is not list: throw "invalid args"
if not .entries: return ""
 
# print the menu
writeln join "\n", map(fn .e, .i: "{{.i:2}}: {{.e}}", .entries, 1..len .entries)
 
val .idx = number read(
"Select entry #: ",
fn(.x) {
if not .x -> RE/^[0-9]+$/: return false
val .y = number .x
.y > 0 and .y <= len(.entries)
},
"invalid selection\n", -1,
)
 
.entries[.idx]
}
 
writeln .select(["fee fie", "eat pi", "huff and puff", "tick tock"])
</syntaxhighlight>
 
{{out}}
<pre> 1: fee fie
2: eat pi
3: huff and puff
4: tick tock
Select entry #: 7
invalid selection
Select entry #: 2
eat pi</pre>
 
=={{header|Logo}}==
{{incorrect|Logo|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
{{works with|UCB Logo}}
<langsyntaxhighlight lang="logo">to select :prompt [:options]
foreach :options [(print # ?)]
forever [
Line 535 ⟶ 1,877:
[Which is from the three pigs?]
[fee fie] [huff and puff] [mirror mirror] [tick tock])
</syntaxhighlight>
</lang>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function choiceselect (choiceslist)
if not list or #list == 0 then
for i, v in ipairs(choices) do print(i, v) end
return ""
end
local last, sel = #list
repeat
for i,option in ipairs(list) do
io.write(i, ". ", option, "\n")
end
io.write("Choose an item (1-", tostring(last), "): ")
sel = tonumber(string.match(io.read("*l"), "^%d+$"))
until type(sel) == "number" and sel >= 1 and sel <= last
return list[math.floor(sel)]
end
 
print("EnterNothing:", yourselect choice"{})
print()
local selection = io.read() + 0
print("You chose:", select {"fee fie", "huff and puff", "mirror mirror", "tick tock"})</syntaxhighlight>
 
{{out}}
if choices[selection] then print(choices[selection])
<pre>
else choice(choices)
Nothing:
end
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 0
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): a
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 1.7
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 10
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 3
You chose: mirror mirror
</pre>
=={{header|M2000 Interpreter}}==
We use the dropdown menu, from M2000 Console. This menu open at text coordinates (moving to better position if can't fit to screen). We can choose something with enter + arrows or using mouse pointer. There is a way to feed the internal menu array, one by one, first using Menu without parameters, to clear the previous loaded menu, then using Menu + string expression, for each new item, and finally for opening the menu, we place: Menu !
 
The If$() statement return for boolean -1, 0 or for any number>0, as the Nth expression (from 1 to the last one).
 
<syntaxhighlight lang="m2000 interpreter">
Module TestMenu {
Print "Make your choice: ";
Do
Menu "fee fie", "huff and puff", "mirror mirror", "tick tock"
when menu=0
Print Menu$(Menu)
Print "That was the ";If$(Menu->"1st","2nd","3rd","4th");" option, bravo;"
}
TestMenu
</syntaxhighlight>
{{out}}
<pre>
Make your choice: mirror mirror
That was the 3rd option, bravo;
</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
'''Interpreter:''' Wolfram Desktop and Wolfram Desktop Kernel
{{works with|Wolfram Language|12}}
Redisplays the list of choices on every invalid input as per the task description. In the notebook interface (of Wolfram Desktop, at least), Print[] would most pragmatically be located outside of the loop because Input[] uses a dialog box.
 
<syntaxhighlight lang="mathematica">textMenu[data_List] := Module[{choice},
If[Length@data == 0, Return@""];
While[!(IntegerQ@choice && Length@data >= choice > 0),
MapIndexed[Print[#2[[1]], ") ", #1]&, data];
choice = Input["Enter selection..."]
];
data[[choice]]
]</syntaxhighlight>
{{out|Kernel (REPL) output|note=function definition omitted}}
<pre>Wolfram Desktop Kernel (using Wolfram Language 12.0.0) for Microsoft Windows (64-bit)
Copyright 1988-2019 Wolfram Research, Inc.
 
In[1]:= (*! ELIDED !*)
 
In[2]:= textMenu[{}]
 
Out[2]=
 
In[3]:= textMenu[{"fee fie", "huff and puff", "mirror mirror", "tick tock"}]
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...0
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...5
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...-1
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...fee fie
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...3
 
Out[3]= mirror mirror</pre>
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">function sucess = menu(list)
if numel(list) == 0
sucess = '';
return
end
 
while(true)
disp('Please select one of these options:');
for i = (1:numel(list))
disp([num2str(i) ') ' list{i}]);
end
disp([num2str(numel(list)+1) ') exit']);
try
key = input(':: ');
if key == numel(list)+1
break
elseif (key > numel(list)) || (key < 0)
continue
else
disp(['-> ' list{key}]);
end
catch
continue
end
end
sucess = true;
end
</syntaxhighlight>
 
=={{header|min}}==
choice{"fee fie", "huff and puff", "mirror mirror", "tick tock"}</lang>
{{works with|min|0.19.3}}
min has an operator <code>choose</code> that nearly conforms to this task. The input list is altered so that the choice can be returned, and the empty list case is handled.
<syntaxhighlight lang="min">(
:prompt =list
(list bool)
(list (' dup append) map prompt choose)
("") if
) :menu
 
("fee fie" "huff and puff" "mirror mirror" "tick tock")
"Enter an option" menu
"You chose: " print! puts!</syntaxhighlight>
{{out}}
<pre>
Enter an option
1 - fee fie
2 - huff and puff
3 - mirror mirror
4 - tick tock
Enter your choice (1 - 4): 5
Invalid choice.
1 - fee fie
2 - huff and puff
3 - mirror mirror
4 - tick tock
Enter your choice (1 - 4): 1
You chose: fee fie
</pre>
 
=={{header|Modula-2}}==
{{incorrect|Modula-2|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<syntaxhighlight lang="modula2">MODULE Menu;
 
FROM InOut IMPORT WriteString, WriteCard, WriteLn, ReadCard;
 
CONST StringLength = 100;
MenuSize = 4;
 
TYPE String = ARRAY[0..StringLength-1] OF CHAR;
 
VAR menu : ARRAY[0..MenuSize] OF String;
selection, index : CARDINAL;
 
BEGIN
menu[1] := "fee fie";
menu[2] := "huff and puff";
menu[3] := "mirror mirror";
menu[4] := "tick tock";
FOR index := 1 TO HIGH(menu) DO
WriteString("[");
WriteCard( index,1);
WriteString( "] ");
WriteString( menu[index]);
WriteLn;
END;(*of FOR*)
WriteString("Choose what you want : ");
ReadCard(selection);
IF (selection <= HIGH(menu)) AND (selection > 0) THEN
WriteString("You have chosen: ");
WriteString( menu[selection]);
WriteLn;
ELSE
WriteString("Selection is out of range!");
WriteLn;
END (*of IF*)
END Menu.</syntaxhighlight>
 
=={{header|MUMPS}}==
<syntaxhighlight lang="mumps">MENU(STRINGS,SEP)
;http://rosettacode.org/wiki/Menu
NEW I,A,MAX
;I is a loop variable
;A is the string read in from the user
;MAX is the number of substrings in the STRINGS list
;SET STRINGS="fee fie^huff and puff^mirror mirror^tick tock"
SET MAX=$LENGTH(STRINGS,SEP)
QUIT:MAX=0 ""
WRITEMENU
FOR I=1:1:MAX WRITE I,": ",$PIECE(STRINGS,SEP,I),!
READ:30 !,"Choose a string by its index: ",A,!
IF (A<1)!(A>MAX)!(A\1'=A) GOTO WRITEMENU
KILL I,MAX
QUIT $PIECE(STRINGS,SEP,A)</syntaxhighlight>
Usage:<pre>
USER>W !,$$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^")
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Choose a string by its index: 3
mirror mirror
USER>W !,$$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^")
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Choose a string by its index: 5
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Choose a string by its index: A
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Choose a string by its index: 0
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Choose a string by its index: 1
fee fie
</pre>
 
=={{header|Nanoquery}}==
{{trans|Ursa}}
<syntaxhighlight lang="nanoquery">def _menu($items)
for ($i = 0) ($i < len($items)) ($i = $i + 1)
println " " + $i + ") " + $items[$i]
end
end
 
def _ok($reply, $itemcount)
try
$n = int($reply)
return (($n >= 0) && ($n < $itemcount))
catch
return $false
end
end
 
def selector($items, $pmt)
// Prompt to select an item from the items
if (len($items) = 0)
return ""
end
$reply = -1
$itemcount = len($items)
while !_ok($reply, $itemcount)
_menu($items)
println $pmt
$reply = int(input())
end
return $items[$reply]
end
 
$items = list()
append $items "fee fie" "huff and puff" "mirror mirror" "tick tock"
$item = selector($items, "Which is from the three pigs: ")
println "You chose: " + $item</syntaxhighlight>
 
=={{header|Nim}}==
{{trans|Python}}
<syntaxhighlight lang="nim">import strutils, rdstdin
proc menu(xs: openArray[string]) =
for i, x in xs: echo " ", i, ") ", x
proc ok(reply: string; count: Positive): bool =
try:
let n = parseInt(reply)
return 0 <= n and n < count
except: return false
proc selector(xs: openArray[string]; prompt: string): string =
if xs.len == 0: return ""
var reply = "-1"
while not ok(reply, xs.len):
menu(xs)
reply = readLineFromStdin(prompt).strip()
return xs[parseInt(reply)]
const xs = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
let item = selector(xs, "Which is from the three pigs: ")
echo "You chose: ", item</syntaxhighlight>
 
{{out}}
<pre> 0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: foo
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 4
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 2
You chose: mirror mirror</pre>
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">
<lang ocaml>let rec select choices prompt = (* "choices" is an array of strings *)
let select ?(prompt="Choice? ") = function
if Array.length choices = 0 then invalid_arg "no choices";
| [] -> ""
Array.iteri (Printf.printf "%d: %s\n") choices;
| choices ->
print_string prompt;
let index = read_int let rec menu () in=
if index >= 0 &&List.iteri index(Printf.printf <"%d: Array.length%s\n") choices then;
choices.(index) print_string prompt;
try List.nth choices (read_int ())
else
select choices prompt</langwith _ -> menu ()
in menu ()
</syntaxhighlight>
 
Example use in the REPL:
<syntaxhighlight lang="ocaml">
# select ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"];;
0: fee fie
1: huff and puff
2: mirror mirror
3: tick tock
Choice? 2
- : string = "mirror mirror"
</syntaxhighlight>
 
=={{header|OpenEdge/Progress}}==
<syntaxhighlight lang="progress">FUNCTION bashMenu RETURNS CHAR(
i_c AS CHAR
):
DEF VAR ii AS INT.
DEF VAR hfr AS HANDLE.
DEF VAR hmenu AS HANDLE EXTENT.
DEF VAR ikey AS INT.
DEF VAR ireturn AS INT INITIAL ?.
 
EXTENT( hmenu ) = NUM-ENTRIES( i_c ).
 
CREATE FRAME hfr ASSIGN
WIDTH = 80
HEIGHT = NUM-ENTRIES( i_c )
PARENT = CURRENT-WINDOW
VISIBLE = TRUE
.
 
DO ii = 1 TO NUM-ENTRIES( i_c ):
 
CREATE TEXT hmenu ASSIGN
FRAME = hfr
FORMAT = "x(79)"
SCREEN-VALUE = SUBSTITUTE( "&1. &2", ii, ENTRY( ii, i_c ) )
ROW = ii
VISIBLE = TRUE
.
END.
 
IF i_c = "" THEN
ireturn = 1.
 
DO WHILE ireturn = ?:
 
READKEY.
ikey = INTEGER( CHR( LASTKEY ) ) NO-ERROR.
IF ikey >= 1 AND ikey <= NUM-ENTRIES( i_c ) THEN
ireturn = ikey.
 
END.
 
RETURN ENTRY( ireturn, i_c ).
 
END FUNCTION.
 
MESSAGE
bashMenu( "fee fie,huff and puff,mirror mirror,tick tock" )
VIEW-AS ALERT-BOX.</syntaxhighlight>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
fun {Select Prompt Items}
case Items of nil then ""
Line 593 ⟶ 2,357:
in
{System.showInfo "You chose: "#Item}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
{{incorrect|PARI/GP|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<syntaxhighlight lang="parigp">choose(v)=my(n);for(i=1,#v,print(i". "v[i]));while(type(n=input())!="t_INT"|n>#v|n<1,);v[n]
choose(["fee fie","huff and puff","mirror mirror","tick tock"])</syntaxhighlight>
 
=={{header|Pascal}}==
{{works with|Free_Pascal}}
Tested with Free Pascal 2.6.4 (arm).
<syntaxhighlight lang="pascal">program Menu;
{$ASSERTIONS ON}
uses
objects;
var
MenuItems :PUnSortedStrCollection;
selected :string;
 
Function SelectMenuItem(MenuItems :PUnSortedStrCollection):string;
var
i, idx :integer;
code :word;
choice :string;
begin
// Return empty string if the collection is empty.
if MenuItems^.Count = 0 then
begin
SelectMenuItem := '';
Exit;
end;
 
repeat
for i:=0 to MenuItems^.Count-1 do
begin
writeln(i+1:2, ') ', PString(MenuItems^.At(i))^);
end;
write('Make your choice: ');
readln(choice);
// Try to convert choice to an integer.
// Code contains 0 if this was successful.
val(choice, idx, code)
until (code=0) and (idx>0) and (idx<=MenuItems^.Count);
// Return the selected element.
SelectMenuItem := PString(MenuItems^.At(idx-1))^;
end;
 
begin
// Create an unsorted string collection for the menu items.
MenuItems := new(PUnSortedStrCollection, Init(10, 10));
 
// Add some menu items to the collection.
MenuItems^.Insert(NewStr('fee fie'));
MenuItems^.Insert(NewStr('huff and puff'));
MenuItems^.Insert(NewStr('mirror mirror'));
MenuItems^.Insert(NewStr('tick tock'));
 
// Display the menu and get user input.
selected := SelectMenuItem(MenuItems);
writeln('You chose: ', selected);
 
dispose(MenuItems, Done);
 
// Test function with an empty collection.
MenuItems := new(PUnSortedStrCollection, Init(10, 10));
 
selected := SelectMenuItem(MenuItems);
// Assert that the function returns an empty string.
assert(selected = '', 'Assertion failed: the function did not return an empty string.');
 
dispose(MenuItems, Done);
end.</syntaxhighlight>
 
{{out}}
<pre>
$ bin/menu
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Make your choice: abc
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Make your choice: 99
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Make your choice: 3
You chose: mirror mirror
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">sub menu
{
my ($prompt,@array) = @_;
Line 613 ⟶ 2,468:
$a = &menu($prompt,@a);
 
print "You chose: $a\n";</langsyntaxhighlight>
 
=={{header|Phix}}==
<syntaxhighlight lang="phix">function menu_select(sequence items, object prompt)
sequence res = ""
items = remove_all("",items)
if length(items)!=0 then
while 1 do
for i=1 to length(items) do
printf(1,"%d) %s\n",{i,items[i]})
end for
puts(1,iff(atom(prompt)?"Choice?":prompt))
res = scanf(trim(gets(0)),"%d")
puts(1,"\n")
if length(res)=1 then
integer nres = res[1][1]
if nres>0 and nres<=length(items) then
res = items[nres]
exit
end if
end if
end while
end if
return res
end function
constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"}
constant prompt = "Which is from the three pigs? "
string res = menu_select(items,prompt)
printf(1,"You chose %s.\n",{res})</syntaxhighlight>
 
=={{header|PHP}}==
<syntaxhighlight lang="php"><?php
$stdin = fopen("php://stdin", "r");
$allowed = array(1 => 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock');
 
for(;;) {
foreach ($allowed as $id => $name) {
echo " $id: $name\n";
}
echo "Which is from the four pigs: ";
$stdin_string = fgets($stdin, 4096);
if (isset($allowed[(int) $stdin_string])) {
echo "You chose: {$allowed[(int) $stdin_string]}\n";
break;
}
}</syntaxhighlight>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(de choose (Prompt Items)
(use N
(loop
(for (I . Item) Items
(prinl I ": " Item) )
(prin Prompt " ")
(flush)
(NIL (setq N (in NIL (read))))
(T (>= (length Items) N 1) (prinl (get Items N))) ) ) )
(choose "Which is from the three pigs?"
'("fee fie" "huff and puff" "mirror mirror" "tick tock") )</syntaxhighlight>
{{out}}
<pre>
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? q
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? 5
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? 2
huff and puff
</pre>
 
=={{header|PL/I}}==
{{incorrect|PL/I|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<lang PL/I>
<syntaxhighlight lang="pl/i">
 
test: proc options (main);
 
Line 634 ⟶ 2,569:
 
end test;
</syntaxhighlight>
</lang>
 
=={{header|PicoLispPowerShell}}==
<syntaxhighlight lang="powershell">
<lang PicoLisp>(de choose (Prompt Items)
function Select-TextItem
(use N
{
(loop
<#
(for (I . Item) Items
.SYNOPSIS
(prinl I ": " Item) )
Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list.
(prin Prompt " ")
.DESCRIPTION
(NIL (setq N (in NIL (read))))
Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list;
(T (>= (length Items) N 1) (get Items N)) ) ) )
Prompts the user to enter a number;
Returns an object corresponding to the selected index number.
.PARAMETER InputObject
An array of objects.
.PARAMETER Prompt
The menu prompt string.
.EXAMPLE
“fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem
.EXAMPLE
“huff and puff”, “fee fie”, “tick tock”, “mirror mirror” | Sort-Object | Select-TextItem -Prompt "Select a string"
.EXAMPLE
Select-TextItem -InputObject (Get-Process)
.EXAMPLE
(Get-Process | Where-Object {$_.Name -match "notepad"}) | Select-TextItem -Prompt "Select a Process" | Stop-Process -ErrorAction SilentlyContinue
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true)]
$InputObject,
 
[Parameter(Mandatory=$false)]
(choose "Which is from the three pigs?"
[string]
'("fee fie" "huff and puff" "mirror mirror" "tick tock") )</lang>
$Prompt = "Enter Selection"
Output:
)
<pre>1: fee fie
 
2: huff and puff
Begin
3: mirror mirror
{
4: tick tock
$menuOptions = @()
Which is from the three pigs? 2
}
-> "huff and puff"</pre>
Process
{
$menuOptions += $InputObject
}
End
{
if(!$inputObject){
return ""
}
do
{
[int]$optionNumber = 1
 
foreach ($option in $menuOptions)
{
Write-Host ("{0,3}: {1}" -f $optionNumber,$option)
 
$optionNumber++
}
 
Write-Host ("{0,3}: {1}" -f 0,"To cancel")
 
$choice = Read-Host $Prompt
 
$selectedValue = ""
 
if ($choice -gt 0 -and $choice -le $menuOptions.Count)
{
$selectedValue = $menuOptions[$choice - 1]
}
 
}
until ($choice -match "^[0-9]+$" -and ($choice -eq 0 -or $choice -le $menuOptions.Count))
 
return $selectedValue
}
}
 
“fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem -Prompt "Select a string"
</syntaxhighlight>
 
{{Out}}
<pre>
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
0: To cancel
Select a string: 3
mirror mirror
</pre>
 
=={{header|ProDOS}}==
{{incorrect|ProDOS|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<syntaxhighlight lang="text">
:a
printline ==========MENU==========
printline 1. Fee Fie
printline 2. Huff Puff
printline 3. Mirror, Mirror
printline 4. Tick, Tock
editvar /newvar /value=a /userinput=1 /title=What page do you want to go to?
if -a- /hasvalue 1 printline You chose a line from the book Jack and the Beanstalk. & exitcurrentprogram 1
if -a- /hasvalue 2 printline You chose a line from the book The Three Little Pigs. & exitcurrentprogram 1
if -a- /hasvalue 3 printline You chose a line from the book Snow White. & exitcurrentprogram 1
if -a- /hasvalue 4 printline You chose a line from the book Beauty and the Beast. & exitcurrentprogram 1
printline You either chose an invalid choice or didn't chose.
editvar /newvar /value=goback /userinput=1 /title=Do you want to chose something else?
if -goback- /hasvalue y goto :a else exitcurrentprogram 1 </syntaxhighlight>
 
=={{header|Prolog}}==
{{works with|SWI-Prolog|6}}
<syntaxhighlight lang="prolog">
rosetta_menu([], "") :- !. %% Incase of an empty list.
rosetta_menu(Items, SelectedItem) :-
repeat, %% Repeat until everything that follows is true.
display_menu(Items), %% IO
get_choice(Choice), %% IO
number(Choice), %% True if Choice is a number.
nth1(Choice, Items, SelectedItem), %% True if SelectedItem is the 1-based nth member of Items, (fails if Choice is out of range)
!.
 
display_menu(Items) :-
nl,
foreach( nth1(Index, Items, Item),
format('~w) ~s~n', [Index, Item]) ).
 
get_choice(Choice) :-
prompt1('Select a menu item by number:'),
read(Choice).
</syntaxhighlight>
 
Example run:
 
<syntaxhighlight lang="prolog">
?- rosetta_menu(["fee fie", "huff and puff", "mirror mirror", "tick tock"], String).
 
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Select a menu item by number:a.
 
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Select a menu item by number:10.
 
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Select a menu item by number:3.
String = "mirror mirror".
</syntaxhighlight>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">If OpenConsole()
Define i, txt$, choice
Dim txts.s(4)
Line 683 ⟶ 2,755:
TheStrings:
Data.s "fee fie", "huff And puff", "mirror mirror", "tick tock"
EndDataSection</langsyntaxhighlight>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">def _menu(items):
for indexitem in enumerate(items):
print (" %2i) %s" % indexitem)
Line 712 ⟶ 2,784:
items = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']
item = selector(items, 'Which is from the three pigs: ')
print ("You chose: " + item)</langsyntaxhighlight>
 
Sample runs:
Line 741 ⟶ 2,813:
 
=={{header|R}}==
 
Uses [http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/base/html/menu.html menu].
<langsyntaxhighlight Rlang="r">showmenu <- function(choices = NULL)
{
if (is.null(choices)) return("")
choices <- c("fee fie", "huff and puff", "mirror mirror", "tick tock")
ans <- menu(choices)
if(ans==0) "" else choices[ans]
 
}
str <- showmenu(c("fee fie", "huff and puff", "mirror mirror", "tick tock"))</lang>
str <- showmenu()
</syntaxhighlight>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
#lang racket
 
(define (menu choices)
(cond [(null? choices) ""]
[else (for ([c choices] [i (in-naturals 1)]) (printf "~a. ~a\n" i c))
(printf "Enter a number: ")
(define n (string->number (read-line)))
(or (and (exact-integer? n)
(<= 1 n (length choices))
(list-ref choices (sub1 n)))
(menu choices))]))
 
(menu '("fee fie" "huff and puff" "mirror mirror" "tick tock"))
</syntaxhighlight>
 
Sample Run:
<pre>
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: three
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: help
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3!!
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3
"mirror mirror"
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub menu ( $prompt, @items ) {
return '' unless @items.elems;
repeat until my $selection ~~ /^ \d+ $/ && @items[--$selection] {
my $i = 1;
say " {$i++}) $_" for @items;
$selection = prompt $prompt;
}
return @items[$selection];
}
 
my @choices = 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock';
my $prompt = 'Enter the number corresponding to your selection: ';
 
my $answer = menu( $prompt, [] );
say "You chose: $answer" if $answer.chars;
 
$answer = menu( $prompt, @choices );
say "You chose: $answer" if $answer.chars;</syntaxhighlight>
 
=={{header|REBOL}}==
{{incorrect|REBOL|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
<lang REBOL>REBOL [
<syntaxhighlight lang="rebol">REBOL [
Title: "Text Menu"
Author: oofoe
Date: 2009-12-08
URL: http://rosettacode.org/wiki/Select
]
Line 773 ⟶ 2,912:
choice: ask "Which is from the three pigs? "
]
print ["You chose:" pick choices to-integer choice]</langsyntaxhighlight>
 
Output:
Line 793 ⟶ 2,932:
Which is from the three pigs? 2
You chose: huff and puff</pre>
=={{header|Red}}==
<syntaxhighlight lang="red">Red ["text menu"]
 
menu: function [items][
print either empty? items [""] [until [
repeat n length? items [print [n ":" items/:n]]
attempt [pick items to-integer ask "Your choice: "]
]]
]</syntaxhighlight>
 
{{out}}
 
<pre>>> menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"]
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Your choice: azerty
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Your choice: 7
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Your choice: 3
mirror mirror
>> menu []
 
>> </pre>
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program displays a list, then prompts the user for a selection number (integer).*/
do forever /*keep prompting until response is OK. */
call list_create /*create the list from scratch. */
call list_show /*display (show) the list to the user.*/
if #==0 then return '' /*if list is empty, then return null.*/
say right(' choose an item by entering a number from 1 ───►' #, 70, '═')
parse pull x /*get the user's choice (if any). */
 
select
when x='' then call sayErr "a choice wasn't entered"
when words(x)\==1 then call sayErr 'too many choices entered:'
when \datatype(x,'N') then call sayErr "the choice isn't numeric:"
when \datatype(x,'W') then call sayErr "the choice isn't an integer:"
when x<1 | x># then call sayErr "the choice isn't within range:"
otherwise leave /*this leaves the DO FOREVER loop.*/
end /*select*/
end /*forever*/
/*user might've entered 2. or 003 */
x=x/1 /*normalize the number (maybe). */
say; say 'you chose item' x": " #.x
return #.x /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
list_create: #.1= 'fee fie' /*this is one method for list-building.*/
#.2= 'huff and puff'
#.3= 'mirror mirror'
#.4= 'tick tock'
#=4 /*store the number of choices in # */
return /*(above) is just one convention. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
list_show: say /*display a blank line. */
do j=1 for # /*display the list of choices. */
say '[item' j"] " #.j /*display item number with its choice. */
end /*j*/
say /*display another blank line. */
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
sayErr: say; say '***error***' arg(1) x; say; return</syntaxhighlight>
{{out|output|text=&nbsp; (which includes what the user entered):}}
<pre>
[item 1] fee fie
[item 2] huff and puff
[item 3] mirror mirror
[item 4] tick tock
 
════════════════════ choose an item by entering a number from 1 ───► 4
2 ◄■■■■■■■■■■■■■■■■■■■■■■ what the user entered at the terminal.
 
you chose item 2: huff and puff
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
aList = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
selected = menu(aList, "please make a selection: ")
see "" + selected + nl
func menu aList, prompt
ndex = 1
while index>0 and index<=len(aList)
for index = 1 to len(aList)
if aList[index]!="" see "" + index + " : " + aList[index] + " " ok
next
see nl
see prompt
give select
index = number(select)
see "" + aList[index] + nl
if select!=string(index) index = -1 ok
if index>=0 if index<=len(aList) if aList[index]="" index = -1 ok ok ok
end
return aList[index]
</syntaxhighlight>
Output:
<pre>
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
please make a selection: 2
huff and puff
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
please make a selection: 1
fee fie
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
please make a selection: 4
tick tock
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
please make a selection: 3
mirror mirror
</pre>
 
=={{header|RPL}}==
≪ → prompt options
≪ '''IF''' options SIZE '''THEN'''
prompt options 1 CHOOSE
'''IF''' NOT '''THEN''' "" '''END'''
'''ELSE''' "" '''END'''
≫ '<span style="color:blue">SELECT</span>' STO
 
"Make a choice" { } <span style="color:blue">SELECT</span>
"Make a choice" { "fee fie" "huff and puff" "mirror mirror" "tick tock" } <span style="color:blue">SELECT</span>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">
<lang ruby>def select(prompt, items)
def return "" ifselect(prompt, items.length == 0[])
if items.empty?
while true
''
items.each_index {|i| puts "#{i}. #{items[i]}"}
else
print "#{prompt}: "
beginanswer = -1
until (0...items.length).cover?(answer)
answer = Integer(gets())
items.each_with_index {|i,j| puts "#{j}. #{i}"}
rescue ArgumentError
redoprint "#{prompt}: "
begin
answer = Integer(gets)
rescue ArgumentError
redo
end
end
return items[answer] if answer.between?(0, items.length - 1)
end
end
 
# test empty list
response = select("'Which is empty", []')
puts "empty list returns: >#{response}<\n"
puts ""
 
# "real" test
items = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']
response = select("'Which is from the three pigs"', items)
puts "you chose: >#{response}<"</lang>
</syntaxhighlight>
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">dim choose$(5)
choose$(1) = "1 Fee Fie"
choose$(2) = "2 Huff Puff"
choose$(3) = "3 Mirror, Mirror"
choose$(4) = "4 Tick, Tock"
choose$(5) = "Exit"
 
[start]
print "Menu Selection"
listbox #lb,choose$(),5
button #sel, "Accept",[select]
wait
 
[select]
selected$=#lb selection$()
print " "
if selected$<>"" then
print "You selected ";selected$
else
print "No selection made"
end if
button #con, "Continue",[go2]
wait
[go2]
if selected$<>"Exit" then
cls
goto [start]
else
cls
end
end if</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
fn menu_select<'a>(items: &'a [&'a str]) -> &'a str {
if items.len() == 0 {
return "";
}
 
let stdin = std::io::stdin();
let mut buffer = String::new();
 
loop {
for (i, item) in items.iter().enumerate() {
println!("{}) {}", i + 1, item);
}
print!("Pick a number from 1 to {}: ", items.len());
 
// Read the user input:
stdin.read_line(&mut buffer).unwrap();
println!();
 
if let Ok(selected_index) = buffer.trim().parse::<usize>() {
if 0 < selected_index {
if let Some(selected_item) = items.get(selected_index - 1) {
return selected_item;
}
}
}
 
// The buffer will contain the old input, so we need to clear it before we can reuse it.
buffer.clear();
}
}
 
fn main() {
// Empty list:
let selection = menu_select(&[]);
println!("No choice: {:?}", selection);
 
// List with items:
let items = [
"fee fie",
"huff and puff",
"mirror mirror",
"tick tock",
];
 
let selection = menu_select(&items);
println!("You chose: {}", selection);
}
</syntaxhighlight>
 
=={{header|Scala}}==
===Scala idiom (Functional)===
<syntaxhighlight lang="text">import scala.util.Try
 
object Menu extends App {
val choice = menu(list)
 
def menu(menuList: Seq[String]): String = {
if (menuList.isEmpty) "" else {
val n = menuList.size
 
def getChoice: Try[Int] = {
println("\n M E N U\n")
menuList.zipWithIndex.map { case (text, index) => s"${index + 1}: $text" }.foreach(println(_))
print(s"\nEnter your choice 1 - $n : ")
Try {
io.StdIn.readInt()
}
}
 
menuList(Iterator.continually(getChoice)
.dropWhile(p => p.isFailure || !(1 to n).contains(p.get))
.next.get - 1)
}
}
 
def list = Seq("fee fie", "huff and puff", "mirror mirror", "tick tock")
 
println(s"\nYou chose : $choice")
}</syntaxhighlight>
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func string: menuSelect (in array string: items, in string: prompt) is func
result
var string: selection is "";
local
var string: item is "";
var integer: index is 0;
var integer: num is 0;
begin
if length(items) <> 0 then
repeat
for item key index range items do
writeln(index <& ". " <& item);
end for;
write(prompt);
readln(num);
until num >= 1 and num <= length(items);
selection := items[num];
end if
end func;
 
const array string: items is [] ("fee fie", "huff and puff", "mirror mirror", "tick tock");
const string: prompt is "Which is from the three pigs? ";
 
const proc: main is func
begin
writeln("You chose " <& menuSelect(items, prompt));
end func;</syntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func menu (prompt, arr) {
arr.len > 0 || return ''
loop {
for i in ^arr {
say " #{i}: #{arr[i]}"
}
var n = Sys.scanln(prompt) \\ return()
n ~~ /^[0-9]+\z/ ? Num(n) : next
arr.exists(n) && return arr[n]
}
}
 
var list = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']
var prompt = 'Please choose an item number: '
 
var answer = menu(prompt, list)
say "You choose: #{answer}"</syntaxhighlight>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">func getMenuInput(selections: [String]) -> String {
guard !selections.isEmpty else {
return ""
}
 
func printMenu() {
for (i, str) in selections.enumerated() {
print("\(i + 1)) \(str)")
}
 
print("Selection: ", terminator: "")
}
 
while true {
printMenu()
 
guard let input = readLine(strippingNewline: true), !input.isEmpty else {
return ""
}
 
guard let n = Int(input), n > 0, n <= selections.count else {
continue
}
 
return selections[n - 1]
}
}
 
let selected = getMenuInput(selections: [
"fee fie",
"huff and puff",
"mirror mirror",
"tick tock"
])
 
print("You chose: \(selected)")</syntaxhighlight>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc select {prompt choices} {
set nc [llength $choices]
if {!$nc} {
Line 839 ⟶ 3,319:
}
}
}</langsyntaxhighlight>
Testing it out interactively...
<langsyntaxhighlight lang="tcl">% puts >[select test {}]<
><
% puts >[select "Which is from the three pigs" {
Line 871 ⟶ 3,351:
4: tick tock
Which is from the three pigs: 2
>huff and puff<</langsyntaxhighlight>
 
=={{header|TI-83 BASIC}}==
TI-83 BASIC does not support lists of strings, so this works by accepting a string containing an arbitrary number of items separated by colons. If you want to use a different delimiter, change the colons on lines 2, 3, 6 and 7 to your symbol of choice.
 
The calculator's screen isn't big enough to display more than 7 (9 on the new C Silver Edition and CE calcs) options at a time, so the display scrolls to accommodate options if necessary. You won't be able to see options that have scrolled off the top of the screen, but they're still accessible from the input.
 
Although TI-BASIC ''can'' handle empty strings, there's no way to give it one through the Input function, so it doesn't have to worry about being "called with an empty list."
 
Input "",Str1 //input as ITEM 1:ITEM 2:ITEM 3...
":"+Str1+":→Str1
Σ(sub(Str1,X,1)=":",X,1,length(Str1→X
0→dim(L₁
For(Z,2,length(Str1
inString(Str1,":",Z-1
1+Ans+.01inString(Str1,":",Ans+1→L₁(1+dim(L₁
ᴇ2fPart(Ans→Z
End
seq(iPart(L₁(X))+.01(ᴇ2fPart(L₁(X))-iPart(L₁(X))),X,1,dim(L₁→L₁
Repeat A>0 and A<X
ClrHome
For(Z,1,dim(L₁
Disp " :"+sub(Str1,iPart(L₁(Z)),ᴇ2fPart(L₁(Z
Output(min(7,Z),1+(Z≤7),Z
End
Input A
End
Disp sub(Str1,iPart(L₁(A)),ᴇ2fPart(L₁(A
 
Output with <tt>FEE FIE:HUFF AND PUFF:MIRROR MIRROR:TICK TOCK</tt>
 
<syntaxhighlight lang="text"> 1:FEE FIE
2:HUFF AND PUFF
3:MIRROR MIRROR
4:TICK TOCK
? [flashing cursor]</syntaxhighlight>
 
 
The language also has a Menu( command, but it doesn't really follow the requirements for the challenge (only up to 7 options allowed, no user input, option is selected using the arrow keys instead of by entering a number, etc)
"FEE FIE→Str0
"HUFF AND PUFF→Str1
"MIRROR MIRROR→Str2
"TICK TOCK→Str3
Menu("CHOOSE",Str0,A,Str1,B,Str2,C,Str3,D)
Lbl A
Disp Str0
Return
Lbl B
Disp Str1
Return
Lbl C
Disp Str2
Return
Lbl D
Disp Str3
 
=={{header|True BASIC}}==
<syntaxhighlight lang="qbasic">DIM menu$(4)
MAT READ menu$
DATA "fee fie", "huff and puff", "mirror mirror", "tick tock"
 
FUNCTION sel$(choices$())
IF UBOUND(choices$) - LBOUND(choices$) = 0 THEN LET sel$ = ""
LET ret$ = ""
DO
FOR i = LBOUND(choices$) TO UBOUND(choices$)
PRINT i; ": "; choices$(i)
NEXT i
PRINT prompt$;
INPUT index
IF index <= UBOUND(choices$) AND index >= LBOUND(choices$) THEN LET ret$ = choices$(index)
LOOP WHILE ret$ = ""
LET sel$ = ret$
END FUNCTION
 
PRINT sel$(menu$())
END</syntaxhighlight>
 
=={{header|UNIX Shell}}==
 
The bash shell with its [[http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml select]] statement.
This example uses the [http://www.softpanorama.org/Scripting/Shellorama/Control_structures/select_statements.shtml Bash select statement], but Bash did not invent this feature. The ''select'' loop comes originally from the [[Korn Shell]], and appears in some other shells. This loop always continues to read menu choices until the script breaks the loop, or the standard input reaches end of file (EOF).
<lang bash>bash$ PS3='Which is from the three pigs: '
 
bash$ select phrase in 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock'; do
* If the user enters a blank line, the ''select'' loop repeats the list of choices. This is the only way to print the list again. An invalid choice only repeats the prompt, not the list.
> if [[ -n $phrase ]]; then
 
> PHRASE=$phrase
Our ''choose'' function wraps a ''select'' loop. This wrapper implements the task requirement to provide an empty string from an empty list of choices. It also breaks the ''select'' loop after the first good choice.
> echo PHRASE is $PHRASE
 
> break
{{works with|bash}}
> else
{{works with|ksh93}}
> echo 'invalid.'
{{works with|pdksh}}
> fi
{{works with|zsh}}
> done
<syntaxhighlight lang="bash"># choose 'choice 1' 'choice 2' ...
# Prints menu to standard error. Prompts with PS3.
# Reads REPLY from standard input. Sets CHOICE.
choose() {
CHOICE= # Default CHOICE is empty string.
[[ $# -gt 0 ]] || return # Return if "$@" is empty.
select CHOICE; do # Select from "$@".
if [[ -n $CHOICE ]]; then
break
else
echo Invalid choice.
fi
done
}
 
PS3='Which is from the three pigs: '
choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock'
[[ -n $CHOICE ]] && echo You chose: $CHOICE
[[ -z $CHOICE ]] && echo No input.</syntaxhighlight>
 
<pre>$ bash menu.sh
1) fee fie
2) huff and puff
Line 890 ⟶ 3,467:
4) tick tock
Which is from the three pigs: 5
Invalid choice.
invalid.
Which is from the three pigs: 2
PHRASEYou ischose: huff and puff
bash$</langpre>
 
<pre>$ zsh menu.sh
1) fee fie 2) huff and puff 3) mirror mirror 4) tick tock
Which is from the three pigs: 2
You chose: huff and puff</pre>
 
==={{header|es}}===
{{incorrect|es|The function should return an empty string if called with an empty list. Please also check if this could really used as a [https://en.wikipedia.org/wiki/Subroutine function aka subroutine.]}}
There is no ''select'' loop, but this ''es'' script provides just enough code to mimic one.
 
* ''Deviation from task:'' When the list of choices is empty, this function returns an empty list, not an empty string.
 
<syntaxhighlight lang="es"># choose 'choice 1' 'choice 2' ...
# Prints menu to standard error. Prompts with $prompt.
# Returns choice. If no input, returns empty list.
fn choose args {
# If args are empty, return empty list.
~ $#args 0 && return
 
# Echo to standard error.
let (reply =; choice =; fn-menu =; fn-ch =) >[1=2] {
fn-menu = {
# Show menu.
let (i = 1) for (c = $args) {
echo $i') '$c
i = `{expr $i + 1}
}
}
fn-ch = {
# Set choice = $args($reply), but ignore error
# if $reply is not a valid index.
choice = <={catch @ e {result} {
result $args($reply)
}}
}
 
menu
forever {
# Show prompt, read reply.
echo -n $prompt
reply = <={%read}
 
# If no input, return empty list.
~ $#reply 0 && return
 
# Parse reply and return choice.
reply = <={%split \ \t\n $reply}
if {~ $#reply 0} {
# Empty reply: show menu again.
menu
} {~ $#reply 1 && ch; ~ $#choice 1} {
return $choice
} {
echo Invalid choice.
}
}
}
}
 
let (choice = <={
local (prompt = 'Which is from the three pigs: ')
choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock'
}) {
~ $#choice 1 && echo You chose: $choice
~ $#choice 0 && echo No input.
}</syntaxhighlight>
 
<pre>$ es menu.es
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Which is from the three pigs: 2
You chose: huff and puff</pre>
 
=={{header|Ursa}}==
{{trans|Python}}
<syntaxhighlight lang="ursa">def _menu (string<> items)
for (decl int i) (< i (size items)) (inc i)
out " " i ") " items<i> endl console
end for
end _menu
 
def _ok (string reply, int itemcount)
try
decl int n
set n (int reply)
return (and (or (> n 0) (= n 0)) (< n itemcount))
catch
return false
end try
end _ok
 
def selector (string<> items, string prompt)
# Prompt to select an item from the items
if (= (size items) 0)
return ""
end if
decl int itemcount reply
set reply -1
set itemcount (size items)
while (not (_ok reply itemcount))
_menu items
out prompt console
set reply (in int console)
end while
return items<(int reply)>
end selector
 
decl string<> items
append "fee fie" "huff and puff" "mirror mirror" "tick tock" items
decl string item
set item (selector items "Which is from the three pigs: ")
out "You chose: " item endl console</syntaxhighlight>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">'The Function
Function Menu(ArrList, Prompt)
Select Case False 'Non-standard usage hahaha
Case IsArray(ArrList)
Menu = "" 'Empty output string for non-arrays
Exit Function
Case UBound(ArrList) >= LBound(ArrList)
Menu = "" 'Empty output string for empty arrays
Exit Function
End Select
'Display menu and prompt
Do While True
For i = LBound(ArrList) To UBound(ArrList)
WScript.StdOut.WriteLine((i + 1) & ". " & ArrList(i))
Next
WScript.StdOut.Write(Prompt)
Choice = WScript.StdIn.ReadLine
'Check if input is valid
If IsNumeric(Choice) Then 'Check for numeric-ness
If CStr(CLng(Choice)) = Choice Then 'Check for integer-ness (no decimal part)
Index = Choice - 1 'Arrays are 0-based
'Check if Index is in array
If LBound(ArrList) <= Index And Index <= UBound(ArrList) Then
Exit Do
End If
End If
End If
WScript.StdOut.WriteLine("Invalid choice.")
Loop
Menu = ArrList(Index)
End Function
 
'The Main Thing
Sample = Array("fee fie", "huff and puff", "mirror mirror", "tick tock")
InputText = "Which is from the three pigs: "
WScript.StdOut.WriteLine("Output: " & Menu(Sample, InputText))</syntaxhighlight>
{{Out}}
<pre>C:\>cscript /nologo menu.vbs
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: cdsfklfm
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: -2
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 3.14159
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 45
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 2
Output: huff and puff</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
import os
 
const list = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
 
fn main() {
pick := menu(list, "Please make a selection: ")
if pick == -1 {
println("Error occured!\nPossibly list or prompt problem.")
exit(-1)
}
else {println("You picked: ${pick}. ${list[pick - 1]}")}
}
 
fn menu(list []string, prompt string) int {
mut index := -1
if list.len == 0 || prompt =='' {return -1}
println('Choices:')
for key, value in list {
println("${key + 1}: ${value}")
}
for index !in [1, 2, 3, 4] {index = os.input('${prompt}').int()}
return index
}
</syntaxhighlight>
 
{{out}}
<pre>
Choices:
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Please make a selection: 2
You picked: 2. huff and puff
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-ioutil}}
<syntaxhighlight lang="wren">import "./ioutil" for Input
 
var menu = Fn.new { |list|
var n = list.count
if (n == 0) return ""
var prompt = "\n M E N U\n\n"
for (i in 0...n) prompt = prompt + "%(i+1). %(list[i])\n"
prompt = prompt + "\nEnter your choice (1 - %(n)): "
var index = Input.integer(prompt, 1, n)
return list[index-1]
}
 
var list = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]
var choice = menu.call(list)
System.print("\nYou chose : %(choice)")</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
M E N U
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
 
Enter your choice (1 - 4): 6
Must be an integer between 1 and 4, try again.
 
M E N U
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
 
Enter your choice (1 - 4): m
Must be an integer between 1 and 4, try again.
 
M E N U
 
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
 
Enter your choice (1 - 4): 4
 
You chose : tick tock
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">string 0;
 
func Menu(List);
int List;
int Size, I, C;
[Size:= List(0);
if Size < 1 then return List(0); \if empty list, return pointer to 0
for I:= 1 to Size-1 do
[IntOut(0, I); Text(0, ": ");
Text(0, List(I)); CrLf(0);
];
CrLf(0);
Text(0, List(Size)); \display prompt
loop [C:= ChIn(0); \buffered keyboard requires Enter key
if C>=^1 & C<=Size-1+^0 then return List(C-^0);
Text(0, "Please enter 1 thru "); IntOut(0, Size-1);
Text(0, ": ");
];
];
 
Text(0, Menu([5, "fee fie", "huff and puff", "mirror mirror", "tick tock",
"Which phrase is from the Three Little Pigs? "]))</syntaxhighlight>
 
Example output:
<pre>
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
 
Which phrase is from the Three Little Pigs? 5
Please enter 1 thru 4: 2
huff and puff
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: https://www.rosettacode.org/wiki/Menu
// by Jjuanhdez, 06/2022
 
dim choose$(5)
restore menudata
for a = 0 to 5 : read choose$(a) : next a
 
print menu$(choose$())
end
 
sub menu$(m$())
clear screen
repeat
print color("green","black") at(0,0) "Menu selection"
vc = 0
b = arraysize(m$(),1)
while vc < 1 or vc > b
for i = 1 to b-1
print i, " ", choose$(i)
next i
print choose$(b)
print
input "Your choice: " c
print at(0,7) "Your choice: "
if c > 0 and c < 6 then
vc = c
print color("yellow","black") at(0,8) choose$(vc)
else
print color("red","black") at(0,8) choose$(0)
break
fi
wend
until vc = 5
end sub
 
label menudata
data "Ack, not good", "fee fie ", "huff and puff"
data "mirror mirror", "tick tock ", "exit "</syntaxhighlight>
 
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">fcn teleprompter(options){
os:=T("exit").extend(vm.arglist); N:=os.len();
if(N==1) return("");
while(1){
Utils.zipWith(fcn(n,o){"%d) %s".fmt(n,o).println()},[0..],os);
a:=ask("Your choice: ");
try{ n:=a.toInt(); if(0<=n<N) return(os[n]); } catch{}
println("Ack, not good");
}
}
 
teleprompter("fee fie" , "huff and puff" , "mirror mirror" , "tick tock")
.println();</syntaxhighlight>
{{out}}
<pre>
0) exit
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Your choice: abc
Ack, not good
0) exit
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Your choice: 3
mirror mirror
</pre>
 
{{omit from|GUISS}}
890

edits