Array length: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 311: Line 311:
<lang JavaScript>function last(list, defaultValue) {
<lang JavaScript>function last(list, defaultValue) {
return list.length ?list[list.length-1] :defaultValue;
return list.length ?list[list.length-1] :defaultValue;
}</lang>

Or use other built-in functions – this, for example, seems fairly clear, and is already 100+ times faster than unoptimised tail recursion in ES5 (testing with a list of 1000 elements):

<lang JavaScript>function last(list, defaultValue) {
return list.slice(-1)[0] || defaultValue;
}</lang>
}</lang>



Revision as of 17:45, 8 October 2015

Task
Array length
You are encouraged to solve this task according to the task description, using any language you may know.

Determine the amount of elements in an array.
As an example use an array holding the strings 'apple' and 'orange'.

See also

ALGOL 68

<lang algol68># UPB returns the upper bound of an array, LWB the lower bound # []STRING fruits = ( "apple", "orange" ); print( ( ( UPB fruits - LWB fruits ) + 1, newline ) ) # prints 2 #</lang>

AWK

The main use of the length()-function is to determine the length of a string.
When used on an array, it returns the number of elements.
Another method to count the elements of the array is by using a variant of for().

<lang awk># usage: awk -f arraylen.awk

function countElements(array) {

 for( e in array ) {c++}
 return c

}

BEGIN {

 array[1] = "apple"
 array[2] = "orange" 
 print "Array length :", length(array), countElements(array)
 
 print "String length:", array[1], length(array[1])

}</lang>

Output:
Array length : 2 2
String length: apple 5

BASIC

<lang basic>DIM X$(1 TO 2) X$(1) = "apple" X$(2) = "orange" PRINT UBOUND(X$) - LBOUND(X$) + 1</lang>

C

C features two kinds of arrays: static (compile-time, fixed size) and dynamic (allocated at runtime).

The length of a dynamic array cannot be acquired from the array itself - its length must be stored elsewhere.

For static arrays:

<lang c>

  1. include <stdio.h>

int main() {

   const char *fruit[2] = { "apples", "oranges" };
   // Acquire the length of the array by dividing the size of all elements (found
   // with sizeof(fruit)) by the size of the first element.
   // Note that since the array elements are pointers to null-terminated character
   // arrays, the size of the first element is actually the size of the pointer
   // type - not the length of the string.
   // This size, regardless of the type being pointed to, is 8 bytes, 4 bytes, or
   // 2 bytes on 64-bit, 32-bit, or 16-bit platforms respectively.
   int length = sizeof(fruit) / sizeof(fruit[0]);
   printf("%d\n", length);
   return 0;

} </lang>

A C pre-processor macro may be created for ease of use:

<lang c>

  1. define ARRAY_LENGTH(A) (sizeof(A) / sizeof(A[0]))

</lang>

Note that these arrays become pointers when passed as a parameter to a function. Thus, the length of an array parameter may not be required directly - a dedicated length parameter would be required.

C++

C++ follows the same rules as C regarding static and dynamic arrays.

However, C++ has an additional std::array type (amongst other collections) in its standard library:

<lang cpp>

  1. include <array>
  2. include <iostream>
  3. include <string>

int main() {

   std::array<std::string, 2> fruit { "apples", "oranges" };
   std::cout << fruit.size();
   return 0;

} </lang>

Note that char* or const char* could have been used instead of std::string.

C#

<lang csharp> using System;

class Program {

   public static void Main()
   {
       var fruit = new[] { "apple", "orange" };
       Console.WriteLine(fruit.Length);
   }

} </lang>

Note that any of the following array declarations could be used:

<lang csharp> var fruit = new[] { "apple", "orange" }; var fruit = new string[] { "apple", "orange" }; string[] fruit = new[] { "apple", "orange" }; string[] fruit = new string[] { "apple", "orange" }; string[] fruit = { "apple", "orange" }; </lang>

A shorter variant could also have been used:

<lang csharp> using static System.Console;

class Program {

   public static void Main()
   {
       WriteLine(new[] { "apples", "oranges" }.Length);
   }

} </lang>

D

<lang d> import std.stdio;

int main() {

   auto fruit = ["apple", "orange"];
   fruit.length.writeln;
   return 0;

} </lang>

Or a somewhat shorter... <lang d> import std.stdio;

void main() {

   ["apple", "orange"].length.writeln;

} </lang>

EchoLisp

<lang scheme> (length '("apple" "orange")) ;; list

  → 2

(vector-length #("apple" "orange")) ;; vector

  → 2

</lang>

Frink

<lang frink> a = ["apple", "orange"] println[length[a]] </lang>

Fortran

Early fortrans offered no protocol for ascertaining the length (or dimensionality) of arrays, though the compiler has this information. Thus a statement such as PRINT A would print all the elements of a variable A according to its definition. A subprogram that received a parameter would have no access to these details, so its parameter might be declared as A(12345) simply to signify that it was an array (rather than an ordinary variable) and the programmer would rely on other data to know the upper bound to employ, for instance via an additional parameter. Any mistakes would cause crashes! On the other hand, with heavy computational tasks, it was common to take advantage of the opportunities. Thus, a subprogram might regard its array parameter as one-dimensional even though the actual parameter was not. Carefully-programmed routines might thusly process a sequence of elements via 1-D indexing, far faster than the 2-D or higher order indexing of the original. Success at this game required understanding how array elements were arranged in multidimensional arrays.

Later fortrans allowed A(*) to signify an array parameter of unstated upper bound, but there was still a problem with higher dimensions. All but the last dimension has to be stated correctly if a multi-dimensional array parameter is to be indexed correctly.

With Fortran 90, a new protocol was introduced, whereby the parameter might be declared as A(:) signifying an array of one dimension, of bounds unstated. A 2-D array would have A(:,:) and so on. Further, arrays could have arbitrary lower bounds as well, as in A(-7:12) but if no colon appeared for a dimension, the lower bound would be assumed to be one so A(2) means an array of two elements, as before. And as before, a bound could be explicitly stated, perhaps via an explicit parameter such as N, but now, the compiler is passing secret additional parameters to the subprogram giving the bounds of the array, and these can be accessed via the library functions LBOUND and UBOUND. For multi-dimensional arrays there are multiple bounds, and an invocation might be UBOUND(A,DIM = 2) but in the example only a one-dimensional array is involved. These facilities are available only if the new MODULE protocol is employed.

The task is in terms of an array holding the texts "Apple" and "Orange", so a CHARACTER*6 element size will do; the subprogram receives yet another secret parameter specifying the size of CHARACTER parameters. This size can be accessed via the LEN function, and, since in principle the index span is arbitrary, no constant index is sure to be a valid index of some single element: thus the LBOUND function is used to finger one that is.

For a simple example, the WRITE(6,*) suffices: write to standard output (the 6), in free-format (the *).

<lang Fortran>

     MODULE EXAMPLE
      CONTAINS
       SUBROUTINE ABOUND(A)
        CHARACTER*(*) A(:)	!One dimensional array, unspecified bounds.
         WRITE (6,*) "Lower bound",LBOUND(A),", Upper bound",UBOUND(A)
         WRITE (6,*) "Element size",LEN(A(LBOUND(A)))
         WRITE (6,*) A
       END SUBROUTINE ABOUND
     END MODULE EXAMPLE
     PROGRAM SHOWBOUNDS
      USE EXAMPLE
      CHARACTER*6 ARRAY(-1:1)
       ARRAY(-1) = "Apple"
       ARRAY(0) = "Orange"
       ARRAY(1) = ""
       CALL ABOUND(ARRAY)
       WRITE (6,*) "But, when it is at home..."
       WRITE (6,*) "L. bound",LBOUND(ARRAY),", U. bound",UBOUND(ARRAY)
     END

</lang>

Output:

Lower bound           1 , Upper bound           3
Element size           6
Apple Orange
But, when it is at home...
L. bound          -1 , U. bound           1

Notice that the subprogram sees the array as an old-style array starting with index one!

FurryScript

<lang furryscript>THE_LIST( <apple> <orange> ) COUNT[ 0 SW ~| COUNT_STEP# 0 SW SU ] COUNT_STEP[ DR 1 SU ]

`THE_LIST COUNT# +<></lang>

F#

<lang fsharp>[|1;2;3|].Length |> printfn "%i"</lang> Or: <lang fsharp>[|1;2;3|] |> Array.length |> printfn "%i"</lang>

Haskell

<lang Haskell>-- Char -> Int length ["apple", "orange"]</lang>

J

Tally (#) returns the length of the leading dimension of an array (or 1 if the array has no dimensions). Shape Of ($) returns the length of each dimension of an array. <lang j> # 'apple';'orange' 2

  $ 'apple';'orange'

2</lang> For the list array example given, the result appears to be the same. The difference is that the result of Tally is a scalar (array of 0 dimensions) whereas the result of Shape Of is a list (1 dimensional array), of length 1 in this case. <lang j> $#'apple';'orange'

  $$'apple';'orange'

1</lang> This might be a clearer concept with a few more examples. Here's an array with two dimensions: <lang j> >'apple';'orange' apple orange

  $>'apple';'orange'

2 6

  #>'apple';'orange'

2</lang> And, here's an array with no dimensions: <lang> 9001 9001

  #9001

1

  $9001

</lang> You can count the number of dimensions of an array (the length of the list of lengths) using #$array: <lang j>

  #$9001

0

  #$'apple';'orange'

1

  #$>'apple';'orange'

2</lang>

Java

<lang java>public class ArrayLength {

   public static void main(String[] args) {
       System.out.println(new String[]{"apple", "orange"}.length);
   }

}</lang>

JavaScript

<lang javascript>console.log(['apple', 'orange'].length);</lang>

However, determining the length of a list, array, or collection may simply be the wrong thing to do.

If, for example, the actual task (undefined here, unfortunately) requires retrieving the final item, while it is perfectly possible to write last in terms of length

<lang JavaScript>function last(lst) {

   return lst[lst.length - 1];

}</lang>

using length has the disadvantage that it leaves last simply undefined for an empty list.

We might do better to drop the narrow focus on length, and instead use a fold (reduce, in JS terms) which can return a default value of some kind.

<lang JavaScript>function last(lst) {

   return lst.reduce(function (a, x) {
       return x;
   }, null);

}</lang>

Alternatively, rather than scanning the entire list to simply get the final value, it might sometimes be better to test the length:

<lang JavaScript>function last(list, defaultValue) {

  return list.length ?list[list.length-1] :defaultValue;

}</lang>

Or use other built-in functions – this, for example, seems fairly clear, and is already 100+ times faster than unoptimised tail recursion in ES5 (testing with a list of 1000 elements):

<lang JavaScript>function last(list, defaultValue) {

   return list.slice(-1)[0] || defaultValue;

}</lang>

ooRexx

<lang oorexx> /* REXX */ a = .array~of('apple','orange') say a~size 'elements' Do e over a

 say e
 End

Say "a[2]="a[2]</lang>

Output:
2 elements
apple
orange
a[2]=orange

Perl 6

<lang perl6>say <apple orange>.elems;</lang>

Output:
2

Phix

<lang Phix>constant fruits = {"apple","orange"} ?length(fruits)</lang>

Output:
2


PHP

<lang php>print count(['apple', 'orange']); // Returns 2</lang>

Python

<lang python>>>> print(len(['apple', 'orange'])) 2 >>> </lang>


R

<lang R> a <- c('apple','orange') # create a vector containing "apple" and "orange" length(a) </lang>

Output:
[1] 2

Racket

Translation of: EchoLisp

<lang racket>#lang racket/base (length '("apple" "orange")) ;; list (vector-length #("apple" "orange")) ;; vector</lang>

Output:
2
2

REXX

<lang rexx>/* REXX ----------------------------------------------

  • The compond variable a. implements an array
  • By convention, a.0 contains the number of elements
  • ---------------------------------------------------*/

a.=0 /* initialize the "array" */ call store 'apple' Call store 'orange' Say 'There are' a.0 'elements in the array:' Do i=1 To a.0

 Say 'Element' i':' a.i
 End

Exit store: Procedure Expose a. z=a.0+1 a.z=arg(1) a.0=z Return</lang>

Output:
There are 2 elements in the array:
Element 1: apple
Element 2: orange

Ruby

<lang ruby>puts ['apple', 'orange'].length # or .size</lang>

SQL

<lang sql>SELECT COUNT() FROM (VALUES ('apple'),('orange'));</lang>

Tcl

<lang tcl>;# not recommanded: set mylistA {apple orange}  ;# actually a string set mylistA "Apple Orange"  ;# same - this works only for simple cases

set lenA [llength $mylistA] puts "$mylistA : $lenA"

  1. better: to build a list, use 'list' and/or 'lappend':

set mylistB [list apple orange "red wine" {green frog}] lappend mylistB "blue bird"

set lenB [llength $mylistB] puts "$mylistB : $lenB" </lang>

Output:
Apple Orange :  2
apple orange {red wine} {green frog} {blue bird} :  5

zkl

zkl doesn't support arrays natively, use lists instead. <lang zkl>List("apple", "orange").len().println() //-->2, == L("apple", "orange") T("apple", "orange").len().println() //-->2, read only list (ROList) </lang>