Compare a list of strings: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎Tcl: Added implementation)
(→‎{{header|Tcl}}: Added a few notes)
Line 62: Line 62:


=={{header|Tcl}}==
=={{header|Tcl}}==
The command form of the <code>eq</code> and <code>&lt;</code> operators (introduced in Tcl 8.5) handle arbitrarily many arguments and will check if they're all equal/ordered. Making the operators work with a list of values is just a matter of using the expansion syntax with them.
<lang tcl>set allEqual [tcl::mathop::eq {*}$strings]
<lang tcl>set allEqual [tcl::mathop::eq {*}$strings]
set allOrdered [tcl::mathop::< {*}$strings]</lang>
set allOrdered [tcl::mathop::< {*}$strings]</lang>

Revision as of 13:18, 28 June 2014

Compare a list of strings is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Given a list of arbitrarily many strings, show how to:

  • test if they are all lexically equal
  • test if every string is lexically less than the one after it (i.e. whether the list is in strict ascending order)

Each of those two tests should result in a single true of false value, which could be used as the condition of an if statement or similar. If the input list has less than two elements, the tests should always return true.

There's no need to provide a complete program & output: Assume that the strings are already stored in an array/list/sequence/tuple variable (whatever is most idiomatic) with the name strings, and just show the expressions for performing those two tests on it (plus of course any include's and custom functions etc. that it needs), with as little distractions as possible.

Try to write your solution in a way that does not modify the original list, but if it does then please add a note to make that clear to readers.

If you need further guidance/clarification, see #Perl and #Python for solutions that use implicit short-circuiting loops, and #Perl_6 for a solution that gets away with simply using a built-in language feature.

Related tasks:


C++

Assuming that the strings variable is of type std::vector<std::string>:

Works with: C++ version 11

<lang cpp>#include <algorithm>

std::is_sorted(strings.begin(), strings.end(),

              [](std::string a, std::string b){ return !(b == a); }) )  // All equal

std::is_sorted(strings.begin(), strings.end(),

              [](std::string a, std::string b){ return !(b < a); }) )  // Strictly ascending</lang>

J

Solution (equality test):<lang j> allEq =: 1 = +/@~: NB. or 1 = #@:~. or -: 1&|. or }.-:}:</lang> Solution (order test):<lang j> asc =: /: -: i.@# NB. or -:&(/:~) etc.</lang> Notes: asc indicates whether y is monotonically increasing, but not necessarily strictly monotonically increasing.

Perl

<lang perl>use List::Util 1.33 qw(all);

all { $strings[0] eq $strings[$_] } 1..$#strings # All equal all { $strings[$_-1] lt $strings[$_] } 1..$#strings # Strictly ascending</lang>

Alternatively, if you can guarantee that the input strings don't contain null bytes, the equality test can be performed by a regex like this:

<lang perl>join("\0", @strings) =~ /^ ( [^\0]*+ ) (?: \0 $1 )* $/x # All equal</lang>

Perl 6

In Perl 6, the [...] meta-operator can be used to turn an infix operator into a list reduction in accordance with its inherent associativity; Since the string comparison operators eq and lt have logical chaining associativity, it does the right thing™:

<lang perl6>[eq] @strings # All equal [lt] @strings # Strictly ascending</lang>

Python

<lang python>all(a == b for a, b in zip(strings, strings[1:]) # All equal all(a < b for a, b in zip(strings, strings[1:]) # Strictly ascending</lang>

Tcl

The command form of the eq and < operators (introduced in Tcl 8.5) handle arbitrarily many arguments and will check if they're all equal/ordered. Making the operators work with a list of values is just a matter of using the expansion syntax with them. <lang tcl>set allEqual [tcl::mathop::eq {*}$strings] set allOrdered [tcl::mathop::< {*}$strings]</lang>