File extension is in extensions list: Difference between revisions
Content deleted Content added
No edit summary |
|||
(11 intermediate revisions by 11 users not shown) | |||
Line 72:
{{trans|Python}}
<
R any(extensions.map(e -> @file_name.lowercase().ends_with(‘.’e.lowercase())))
Line 80:
test([‘MyData.a##’, ‘MyData.tar.Gz’, ‘MyData.gzip’, ‘MyData.7z.backup’, ‘MyData...’, ‘MyData’], [‘zip’, ‘rar’, ‘7z’, ‘gz’, ‘archive’, ‘A##’, ‘tar.bz2’])
test([‘MyData_v1.0.tar.bz2’, ‘MyData_v1.0.bz2’], [‘tar.bz2’])</
{{out}}
Line 95:
=={{header|Action!}}==
<
CHAR FUNC ToLower(CHAR c)
Line 164:
FI
OD
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/File_extension_is_in_extensions_list.png Screenshot from Atari 8-bit computer]
Line 179:
=={{header|Ada}}==
<
with Ada.Strings.Fixed.Equal_Case_Insensitive; use Ada.Strings.Fixed;
with Ada.Strings.Bounded;
Line 220:
Put_Line (": " & Valid_Extension'Image);
end loop;
end Main;</
{{out}}
<pre>
Line 234:
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
<
OP LENGTH = ( STRING str )INT: ( UPB str - LWB str ) + 1;
# returns TRUE if str ends with ending FALSE otherwise #
Line 311:
# test the file names in the extra credit #
test has extension in list( "MyData_v1.0.tar.bz2", ec extensions, TRUE );
test has extension in list( "MyData_v1.0.bz2", ec extensions, FALSE )</
{{out}}
<pre>
Line 322:
MyData_v1.0.tar.bz2 has extension "tar.bz2"
MyData_v1.0.bz2 does not have an extension in the list</pre>
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">ext←{
ex←⎕C'.',¨⍺
ex∨.≡(-≢¨ex)↑¨⊂⎕C⍵
}
test←{
e←'zip' 'rar' '7z' 'gz' 'archive' 'A##' 'tar.bz2'
f←'MyData.a##' 'MyData.tar.Gz' 'MyData.gzip' 'MyData.7z.backup'
f,←'MyData...' 'MyData' 'MyData_v1.0.tar.bz2' 'MyData_V1.0.bz2'
f,[1.5]e∘ext¨f
}</syntaxhighlight>
{{out}}
<pre> MyData.a## 1
MyData.tar.Gz 1
MyData.gzip 0
MyData.7z.backup 0
MyData... 0
MyData 0
MyData_v1.0.tar.bz2 1
MyData_V1.0.bz2 0</pre>
=={{header|Arturo}}==
<
hasExtension?: function [file][
Line 334 ⟶ 357:
loop files 'file ->
print [file "=> hasExtension?:" hasExtension? file]</
{{out}}
Line 344 ⟶ 367:
MyData... => hasExtension?: false
MyData => hasExtension?: false</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">
fileList := "MyData.a##,MyData.tar.Gz,MyData.gzip,MyData.7z.backup,MyData...,MyData,MyData_v1.0.tar.bz2,MyData_v1.0.bz2"
extList := "zip,rar,7z,gz,archive,A##,tar.bz2"
textOut := "File extension is in list (" extList ") ?`n"
loop,parse,fileList,CSV
{
textOut .= A_LoopField " ---> "
lastDotPos := InStr(A_LoopField,".",0,0)
extloop := SubStr(A_LoopField,lastDotPos+1)
if (extloop = "bz2")
{
lastDotPos := InStr(A_LoopField,".",0,0,2)
extloop := SubStr(A_LoopField,lastDotPos+1)
}
if !lastDotPos or !extloop
textOut .= "NO`n"
else if extloop in %extList%
textOut .= "YES`n"
else
textOut .= "NO`n"
}
MsgBox % textOut
ExitApp
</syntaxhighlight>
{{Out}}
<pre>File extension is in list (zip,rar,7z,gz,archive,A##,tar.bz2) ?
MyData.a## ---> YES
MyData.tar.Gz ---> YES
MyData.gzip ---> NO
MyData.7z.backup ---> NO
MyData... ---> NO
MyData ---> NO
MyData_v1.0.tar.bz2 ---> YES
MyData_v1.0.bz2 ---> NO</pre>
=={{header|AWK}}==
Line 349 ⟶ 408:
This solution meets the extended criteria stated in the problem.
<syntaxhighlight lang="awk">
# syntax: GAWK -f FILE_EXTENSION_IS_IN_EXTENSIONS_LIST.AWK
BEGIN {
Line 371 ⟶ 430:
}
exit(0)
}</
{{out}}
<pre>
Line 388 ⟶ 447:
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<
dim extensions$ = {".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"}
Line 407 ⟶ 466:
if flag = False then print filenames$[n]; " -> "; "false"
next n
end</
{{out}}
<pre>
Line 414 ⟶ 473:
==={{header|FreeBASIC}}===
<
Dim As String filenames(1 To 8) => {"MyData.a##", "MyData.tar.gz", _
Line 434 ⟶ 493:
If flag = False Then Print filenames(n); " -> "; "false"
Next n
Sleep</
{{out}}
<pre>MyData.a## -> .a## -> true
Line 449 ⟶ 508:
{{works with|QuickBasic}}
{{trans|FreeBASIC}}
<
FOR i = 1 TO 7
READ d$: extensions$(i) = d$
Line 474 ⟶ 533:
DATA ".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"
DATA "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
DATA "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"</
<pre>
Igual que la entrada de FreeBASIC.
Line 481 ⟶ 540:
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<
FOR i = 1 TO 7
READ d$
Line 506 ⟶ 565:
DATA "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
DATA "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"
END</
{{out}}
<pre>
Line 514 ⟶ 573:
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<
for i = 1 to 7
read d$: extensions$(i) = d$
Line 539 ⟶ 598:
data ".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"
data "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
data "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"</
{{out}}
<pre>
Line 548 ⟶ 607:
=={{header|Batch File}}==
This solution does '''not''' contain support for dots in extension names.
<
@echo off
setlocal enabledelayedexpansion
Line 568 ⟶ 627:
shift
goto loop
</syntaxhighlight>
{{out}}
<pre>
Line 583 ⟶ 642:
===C: dots allowed ===
There is no magic in extensions: they are just trailing characters in names.
<
* File extension is in extensions list (dots allowed).
*
Line 682 ⟶ 741:
getchar();
return 0;
}</
{{out}}
<pre>
Line 712 ⟶ 771:
According to this, an extension is whatever comes after the '''last''' dot. Dotless filename won't match anything.
<
#include <string.h>
#include <stdbool.h>
Line 781 ⟶ 840:
return 0;
}
</syntaxhighlight>
=={{header|C++}}==
This solution allows extensions to contain dots.
<
#include <cctype>
#include <iomanip>
Line 831 ⟶ 890:
test("MyData_v1.0.bz2", extensions);
return 0;
}</
{{out}}
Line 846 ⟶ 905:
=={{header|Clojure}}==
<
(re-find (re-pattern (str "\\." ext "$"))
(clojure.string/lower-case s)))
(defn matches-extension-list [ext-list s]
(some #(matches-extension % s) ext-list))</
It is assumed that when extensions are "added to the system", they will be "normalized" to the expected (lower) case.
<
(map clojure.string/lower-case ext-list))</
{{out}}
Line 879 ⟶ 938:
=={{header|D}}==
===Variant 1===
<syntaxhighlight lang="d">
import std.stdio;
import std.string;
Line 916 ⟶ 975:
</syntaxhighlight>
{{out}}
Line 933 ⟶ 992:
===Variant 2===
<syntaxhighlight lang="d">
import std.stdio;
import std.string;
Line 971 ⟶ 1,030:
}
</syntaxhighlight>
{{out}}
Line 990 ⟶ 1,049:
{{libheader| System.SysUtils}}
{{Trans|D}}
<syntaxhighlight lang="delphi">
program File_extension_is_in_extensions_list;
Line 1,024 ⟶ 1,083:
readln;
end.</
{{out}}
<pre>extensions: [zip rar 7z gz archive A## tar.bz2 ]
Line 1,036 ⟶ 1,095:
MyData_v1.0.tar.bz2 : TRUE
MyData_v1.0.bz2 : FALSE</pre>
=={{header|EasyLang}}==
{{trans|BASIC256}}
<syntaxhighlight lang=text>
exts$[] = [ ".zip" ".rar" ".7z" ".gz" ".archive" ".a##" ".tar.bz2" ]
fnames$[] = [ "MyData.a##" "MyData.tar.gz" "MyData.gzip" "MyData.7z.backup" "MyData..." "MyData" "MyData_v1.0.tar.bz2" "MyData_v1.0.bz2" ]
for fn$ in fnames$[]
ext$ = ""
for ext$ in exts$[]
h = len ext$
if substr fn$ (len fn$ - h + 1) h = ext$
print fn$ & " -> " & ext$ & " -> true"
break 1
.
.
if ext$ = ""
print fn$ & " -> false"
.
.
</syntaxhighlight>
{{out}}
<pre>
MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
=={{header|Factor}}==
This solution allows dots in file extensions.
<
IN: rosetta-code.file-extension-list
Line 1,056 ⟶ 1,146:
filenames [
dup extensions ext-in-list? "%19s %u\n" printf
] each</
{{out}}
<pre>
Line 1,079 ⟶ 1,169:
Petty details include the list employing capitals only, as the match is to not distinguish capital from lower case letters, so in the usual way the candidate extension's text is converted to capitals. The list could be subjected to UPCASE, but it is bad form to damage what might be a constant, and one possibly in read-only storage at that. An internal working copy could be made which would then be fed to UPCASE, except that this would be a waste on every invocation. A further trick involves appending a period to the candidate text so that for example ".JP" becomes ".JP." - otherwise a ".JP" would be found in the sequence ".JPG" which would be wrong, so as a result, the list of texts must have a period appended to its last entry, otherwise it would not be findable. Again, this could be done internally, via <code>INDEX(LIST//".",EXT(1:L)//".")</code> at a run-time cost.
Some systems supply an UPCASE (or similar name) to convert text that hopefully would run faster than this example, which relies on searching for the position in a list of letters. A very common alternative is to calculate using character code numerical values, via something like<
IF (IT.GE.0 .AND. IT.LE.25) TEXT(I:I) = CHAR(IT + ICHAR("A")) !In a-z? Convert!</
A final annoyance is the presence of trailing spaces because character variables are of fixed size and so must be made "surely long enough" for the longest expectation. This may not cause trouble on output as spaces look just as blank as blank space, but they may well cause trouble in the internal tests. Thus integer function LSTNB reports the last non-blank, and so a test text can be presented with no trailing spaces, as in TEST(I)(1:LSTNB(TEST(I))) or similar. With Fortran 2003, there is a facility for redefining the sizes of character variables on-the-fly so that this problem can be evaded.
The MODULE protocol is employed for the convenience of not having to respecify the type of the functions in every calling routine, and also to facilitate the collection of types of characters. Otherwise, prior to F90 there would have to be various COMMON statements, or routines would each simply respecify whatever character sets they needed.<
CHARACTER*10 DIGITS !Integer only.
CHARACTER*11 DDIGITS !With a full stop masquerading as a decimal point.
Line 1,220 ⟶ 1,310:
END DO !On to the next.
END
</syntaxhighlight>
The previous results were when only "image" style files were approved. The approval is no longer so restrictive.
<pre>
Line 1,246 ⟶ 1,336:
=={{header|Go}}==
This allows extensions to include a dot and, in the case of success, displays the extension matched (ignoring case) in the list. In the case of failure, the actual (minimum) file extension is displayed.
<
import (
Line 1,288 ⟶ 1,378:
fmt.Printf("%-20s => %-5t (extension = %s)\n", test, ok, ext)
}
}</
{{out}}
Line 1,304 ⟶ 1,394:
MyData_v1.0.bz2 => false (extension = bz2)
</pre>
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
void local fn DoIt
CFArrayRef extensions = @[@"zip",@"rar",@"7z",@"gz",@"archive",@"A##"]
CFArrayRef filenames = @[@"MyData.a##",@"MyData.tar.Gz",@"MyData.gzip",@"MyData.7z.backup",@"MyData...",@"MyData"]
CFStringRef name
NSLogSetTabInterval( 130 )
for name in filenames
NSLog(@"%@\t",name)
if ( fn ArrayContainsObject( fn ArrayValueForKey( extensions, @"lowercaseString" ), lcase(fn StringPathExtension(name) ) ) )
NSLog(@"true")
else
NSLog(@"false")
end if
next
end fn
fn DoIt
HandleEvents
</syntaxhighlight>
=={{header|Haskell}}==
<
import qualified Data.Char as Ch
Line 1,314 ⟶ 1,429:
isExt :: String -> [String] -> Bool
isExt filename extensions = any (`elem` (tails . toLower $ filename)) $ map toLower extensions</
The code defining isExt could be done point free:
<
Overcoming the one-liner urge on behalf of being more comprehensible would give:
<
where allTails = tails . toLower $ filename
lowerExtensions = map toLower extensions</
Given definition handles composite extensions as well.
Line 1,328 ⟶ 1,443:
'''Testing:'''
<
where
files = [ "MyData.a##"
Line 1,338 ⟶ 1,453:
, "MyData_v1.0.tar.bz2"
, "MyData_v1.0.bz2" ]
extensions = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]</
{{Out}}
<pre>λ> main
Line 1,353 ⟶ 1,468:
We can also express this directly in terms of the '''isSuffix''' function, taking care not to reproduce the small glitch in the draft above, which shows a false positive for '''zip''' in '''.gzip''' (see task description bullet 2).
<syntaxhighlight lang
import Data.List (find, isSuffixOf)
import Data.Maybe (fromMaybe)
----------- FILE EXTENSION IS IN EXTENSIONS LIST ---------
extensionFound :: [String] -> String -> Maybe String
extensionFound xs fp = find (`isSuffixOf` fp)
-
main :: IO ()
main =
Line 1,371 ⟶ 1,487:
(fromMaybe "n/a")
(extensionFound
(
(
[ "MyData.a##"
, "MyData.tar.Gz"
Line 1,383 ⟶ 1,499:
])
------------------------- STRINGS ------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
unlines $
s : fmap (((<>) . rjust
where
rjust
w = maximum (length . xShow <$> xs)
{{Out}}
<pre>Any matching extensions found:
Line 1,410 ⟶ 1,525:
'''Solution:'''
<
isExt=: ('.'&,&.>@[ ([: +./ isSuffix&(tolower@>)/) boxopen@])</
'''Usage:'''
<
TestFiles=: <;._1 ' MyData.a## MyData.tar.Gz MyData.gzip MyData.7z.backup MyData... MyData MyData_v1.0.tar.bz2 MyData_v1.0.bz2'
Exts isExt TestFiles
1 1 0 0 0 0 1 0</
=={{header|Java}}==
Line 1,423 ⟶ 1,538:
{{works with|Java|1.5+}}
<
import java.util.Comparator;
Line 1,456 ⟶ 1,571:
}
}
</syntaxhighlight>
{{out}}
<pre>Extensions: [.txt, .gz, , .bat]
Line 1,470 ⟶ 1,585:
{{works with|Java|6+}}
This version is the same as the main version only replace the definition for <code>extIsIn</code> with:
<
for(int i = 0; i < exts.length; i++){
exts[i] = exts[i].replaceAll("\\.", "");
}
return (new FileNameExtensionFilter("extension test", exts)).accept(new File(test));
}</
It would be one line if not for the dot requirement. <code>FileNameExtensionFilter</code> requires that the extensions have no dots. It also requires that the extensions contain characters (i.e. not the empty string) so that test would need to be removed.
=={{header|JavaScript}}==
This solution may not be the most performant but works for most implementations. Allows for dotted extensions, as well.
'''NOTE''' String.endsWith() was introduced with ECMAScript 6 (ES6), so that is a minimum requirement of your JS processor
<syntaxhighlight lang="javascript">
function fileExtensionInExtensionsList(filename) {
let foundIt = false;
let filenameLC = filename.toLowerCase();
let extensions = ["zip", "rar", "7z", "gz", "archive", "A##" ,"tar.bz2"];
extensions.forEach(extension => {
if (filenameLC.endsWith("." + extension.toLowerCase())) { foundIt = true; }
} );
return foundIt;
}
// perform tests below
var fileNamesToTest = [
"MyData.a##"
,"MyData.tar.Gz"
,"MyData.gzip"
,"MyData.7z.backup"
,"MyData..."
,"MyData"
,"MyData_v1.0.tar.bz2"
,"MyData_v1.0.bz2"
];
fileNamesToTest.forEach(filename => {
console.log(filename + " -> " + fileExtensionInExtensionsList(filename));
});
</syntaxhighlight>
{{out}}
(from tests - function returns true or false)
<pre>
MyData.a## -> true
MyData.tar.Gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
=={{header|jq}}==
Line 1,483 ⟶ 1,646:
{{works with|jq|1.4}}
<
# Output: if the filename ends with one of the extensions (ignoring case), output that extension; else output null.
# Assume that the list of file extensions consists of lower-case strings, including a leading period.
Line 1,492 ⟶ 1,655:
| if list | index($ext) then $ext else null end
else null
end;</
'''Examples:'''
<
| has_extension([".txt", ".c"]) as $ext
| if $ext then "\(.) has extension \($ext)"
else "\"\(.)\" does not have an admissible file extension"
end</
{{out}}
<
"c:" does not have an admissible file extension
"txt" does not have an admissible file extension
Line 1,508 ⟶ 1,671:
foo.c has extension .c
"foo.C++" does not have an admissible file extension
"document.pdf" does not have an admissible file extension</
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
# Test
Line 1,519 ⟶ 1,682:
for f in ["MyData.a##", "MyData.tar.Gz", "MyData.gzip", "MyData.7z.backup", "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
@printf("%20s : %5s\n", f, isext(f, extensions))
end</
{{out}}
Line 1,532 ⟶ 1,695:
=={{header|Kotlin}}==
<
/* implicitly allows for extensions containing dots */
Line 1,555 ⟶ 1,718:
println("${fileName.padEnd(19)} -> ${fileName.isFileExtensionListed(extensions)}")
}
}</
{{out}}
Line 1,570 ⟶ 1,733:
=={{header|Lua}}==
<
local extentions = {"zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"}
local testCases = {
Line 1,596 ⟶ 1,759:
for _, case in pairs(testCases) do
print(case .. ": " .. tostring(extMatch(extentions, case)))
end</
{{out}}
<pre>MyData.a##: true
Line 1,608 ⟶ 1,771:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
CheckExtension[fn_String, e : {_String ..}] := StringMatchQ[ToLowerCase[FileExtension[fn]], Alternatives @@ ToLowerCase[e]]
exts = {"zip", "rar", "7z", "gz", "archive", "A##"};
Line 1,616 ⟶ 1,779:
CheckExtension["MyData.7z.backup", exts]
CheckExtension["MyData..", exts]
CheckExtension["MyData", exts]</
{{out}}
<pre>True
Line 1,630 ⟶ 1,793:
To build the extension list, we can use a compile time function:
<
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
Line 1,642 ⟶ 1,805:
for fileName in fileNameList:
echo fileName, " → ", fileName.splitFile().ext.toLowerAscii() in ExtList</
Another way consists to use “mapIt” from standard module “sequtils”:
<
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
Line 1,653 ⟶ 1,816:
for fileName in fileNameList:
echo fileName, " → ", fileName.splitFile().ext.toLowerAscii() in ExtList</
{{out}}
Line 1,666 ⟶ 1,829:
The “splitFile” procedure no longer works in this case. We have to use “endsWith” from the “strutils” module, which changes the logic:
<
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
Line 1,675 ⟶ 1,838:
for fileName in fileNameList:
echo fileName, " → ", ExtList.anyIt(fileName.toLowerAscii().endsWith(it))</
{{out}}
Line 1,688 ⟶ 1,851:
=={{header|Objeck}}==
<
class FileExtension {
function : Main(args : String[]) ~ Nil {
Line 1,712 ⟶ 1,875:
IO.Console->Print(file)->PrintLine(" does not have an extension in the list");
}
}</
{{out}}
Line 1,730 ⟶ 1,893:
The examples were taken from the [[#AWK|AWK]] code.
<
{
my(v=Vecsmall(s));
Line 1,752 ⟶ 1,915:
ext=["txt","gz","bat","c","c++","exe","pdf"];
filenames=["c:","txt","text.txt","text.TXT","test.tar.gz","test/test2.exe","test","foo.c","foo.C","foo.C++","foo.c#","foo.zkl","document.pdf"];
select(f -> checkExt(ext, f), filenames)</
{{out}}
<pre>%1 = ["text.txt", "text.TXT", "test.tar.gz", "test/test2.exe", "foo.c", "foo.C", "foo.C++", "document.pdf"]</pre>
Line 1,762 ⟶ 1,925:
{{trans|Raku}}
<
my ($filename, @extensions) = @_;
my $extensions = join '|', map quotemeta, @extensions;
scalar $filename =~ / \. (?: $extensions ) $ /xi
}</
Testing:
<
my @files= (
'MyData.a##', 'MyData.tar.Gz', 'MyData.gzip', 'MyData.7z.backup',
Line 1,776 ⟶ 1,939:
printf "%-19s - %s\n",
$_, check_extension($_, @extensions) ? 'true' : 'false'
for @files;</
{{out}}
Line 1,793 ⟶ 1,956:
This solution does support the extra credit in the task
<
$allowed = ['zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2'];
$lc_allowed = array_map('strtolower', $allowed);
Line 1,816 ⟶ 1,979:
printf("%20s : %s \n", $test[0],$result);
}
</syntaxhighlight>
{{out}}
MyData.a## : true
Line 1,828 ⟶ 1,991:
=={{header|Phix}}==
Note there is builtin, however get_file_extension("MyData_v1.0.tar.bz2") yields "bz2", since it scans right-to-left for the '.', and also it also yields "so" for "libglfw.so.3.1" (it saves the "1", and the "3", but when they are all-number it carries on scanning left and replaces if it finds another '.'). So to match the task requirements more precisely we shall write a custom version.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">extensions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">lower</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"zip"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rar"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"7z"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gz"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"archive"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"A##"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tar.bz2"</span><span style="color: #0000FF;">})</span>
Line 1,858 ⟶ 2,021:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-20s %-10s %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ext</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"true"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"false"</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ext</span><span style="color: #0000FF;">,</span><span style="color: #000000;">extensions</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 1,873 ⟶ 2,036:
=={{header|Python}}==
<syntaxhighlight lang="python">
def isExt(fileName, extensions):
return True in map(fileName.lower().endswith, ("." + e.lower() for e in extensions))
</syntaxhighlight>
and we could also enrich the return value to a Maybe option type, returning Nothing if no file extension match is found, or Just the particular extension, if a match is found:
<
Line 1,987 ⟶ 2,150:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>Check for a specific set of file extensions:
Line 2,002 ⟶ 2,165:
=={{header|Racket}}==
<
#lang racket
Line 2,033 ⟶ 2,196:
(for ((f (in-list filenames)))
(printf "~a ~a~%" (~a #:width 20 f) (file-extension-in-list? f extensions)))
</syntaxhighlight>
{{out}}
<pre>
Line 2,051 ⟶ 2,214:
Does the extra credit requirement.
<syntaxhighlight lang="raku"
so $filename ~~ /:i '.' @extensions $/
}
Line 2,062 ⟶ 2,225:
MyData_v1.0.tar.bz2 MyData_v1.0.bz2
>;
say "{$_.fmt: '%-19s'} - {check-extension $_, @extensions}" for @files;</
{{out}}
Line 2,078 ⟶ 2,241:
=={{header|REXX}}==
This REXX version handles the extra credit requirement.
<
$= 'zip rar 7z gz archive A## tar.bz2'; upper $ /*a list of "allowable" file extensions*/
parse arg fn /*obtain optional argument from the CL.*/
Line 2,099 ⟶ 2,262:
end /*k*/ /* [↓] display file, and a nay or yea.*/
say right(@.j, 40) ' ' right( word( "false true", 1 + (k<=#) ), 5)
end /*j*/ /*stick a fork in it, we're all done. */</
{{out|output|text= when using the default input:}}
<pre>
Line 2,113 ⟶ 2,276:
=={{header|Ring}}==
<
# Project : File extension is in extensions list
Line 2,134 ⟶ 2,297:
ok
next
</syntaxhighlight>
Output:
<pre>
Line 2,148 ⟶ 2,311:
=={{header|Ruby}}==
<
if filename.respond_to?(:each)
filename.each do |fn|
Line 2,161 ⟶ 2,324:
end
end
</syntaxhighlight>
{{out}}
<pre>
Line 2,174 ⟶ 2,337:
=={{header|Rust}}==
Does extra credit.
<
let exts = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"];
let filenames = [
Line 2,198 ⟶ 2,361:
}
}
</syntaxhighlight>
{{out}}
<pre>
Line 2,215 ⟶ 2,378:
=={{header|Scala}}==
<
extensions.map { _.toLowerCase }.exists { fileName.toLowerCase endsWith "." + _ }
}
</syntaxhighlight>
=={{header|Sidef}}==
{{trans|Perl}}
<
filename ~~ Regex('\.(' + extensions.map { .escape }.join('|') + ')\z', :i)
}</
Testing:
<
var files = [
Line 2,236 ⟶ 2,399:
for file in files {
printf("%-19s - %s\n", file, check_extension(file, extensions))
}</
{{out}}
<pre>
Line 2,251 ⟶ 2,414:
=={{header|Tcl}}==
<
# This example includes the extra credit.
Line 2,317 ⟶ 2,480:
}
</syntaxhighlight>
{{out}}
<pre>
Line 2,328 ⟶ 2,491:
MyData_v1.0.tar.bz2 true
MyData_v1.0.bz2 false
</pre>
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
const (
extensions = [".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"]
filenames = ["MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup",
"MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
)
fn main() {
outer:
for oidx, file in filenames {
for idx, extension in extensions {
if file.substr_ni(file.len - extension.len, file.len) == extension {
println("${filenames[oidx]} -> ${extensions[idx]} -> true")
continue outer
}
}
println("${filenames[oidx]} -> false")
}
}
</syntaxhighlight>
{{out}}
<pre>
MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
Line 2,334 ⟶ 2,530:
{{libheader|Wren-str}}
{{libheader|Wren-fmt}}
<
import "./fmt" for Fmt
var exts = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]
Line 2,358 ⟶ 2,554:
}
if (!hasExt) Fmt.print("$-20s $-5s", test, hasExt)
}</
{{out}}
Line 2,370 ⟶ 2,566:
MyData_v1.0.tar.bz2 true (extension: tar.bz2)
MyData_v1.0.bz2 false
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">string 0;
func ToUpper(C); \Convert character to upper case
int C;
return if C>=^a & C<=^z then C&$DF else C;
func HasExt(File, Ext); \Return 'true' if File has Ext(ension)
char File, Ext;
int I, J;
[I:= 0;
while File(I) # 0 do I:= I+1;
while File(I) # ^. and I > 0 do I:= I-1;
I:= I+1;
J:= 0;
loop [if ToUpper(File(I+J)) # ToUpper(Ext(J)) then return false;
if Ext(J) = 0 then return true;
J:= J+1;
];
];
int Exts, Ext, Files, Test;
[Exts:= ["zip", "rar", "7z", "gz", "archive", "A##"];
Files:= ["MyData.a##", "MyData.tar.Gz", "MyData.gzip" , "MyData.7z.backup",
"MyData...", "MyData" ];
for Test:= 0 to 5 do
[for Ext:= 0 to 5 do
[if HasExt(Files(Test), Exts(Ext)) then
[Text(0, " true : ");
Ext:= 100;
];
];
if Ext = 6 then Text(0, "false : ");
Text(0, Files(Test));
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
true : MyData.a##
true : MyData.tar.Gz
false : MyData.gzip
false : MyData.7z.backup
false : MyData...
false : MyData
</pre>
=={{header|zkl}}==
<
var [const] extensions=T(".zip",".rar",".7z",".gz",".archive",".a##");
nm,ext:=File.splitFileName(fnm)[-2,*].apply("toLower");
Line 2,383 ⟶ 2,626:
"MyData...","MyData",
"MyData_v1.0.tAr.bz2","MyData_v1.0.bz2");
foreach nm in (nms){ println("%20s : %s".fmt(nm,hasExtension(nm))); }</
{{out}}
<pre>
|