ListasLists

Nota

Los vínculos de la referencia de API de este artículo le llevarán a MSDN.The API reference links in this article will take you to MSDN. La referencia de API de docs.microsoft.com no está completa.The docs.microsoft.com API reference is not complete.

En F#, una lista es una serie ordenada e inmutable de elementos del mismo tipo.A list in F# is an ordered, immutable series of elements of the same type. Para realizar operaciones básicas en listas, use las funciones del módulo de lista.To perform basic operations on lists, use the functions in the List module.

Crear e inicializar listasCreating and Initializing Lists

Para definir una lista, puede enumerar explícitamente los elementos, separados por punto y coma y escritos entre corchetes, tal y como se muestra en la línea de código siguiente.You can define a list by explicitly listing out the elements, separated by semicolons and enclosed in square brackets, as shown in the following line of code.

let list123 = [ 1; 2; 3 ]

También puede insertar saltos de línea entre los elementos, en cuyo caso el signo de punto y coma es opcional.You can also put line breaks between elements, in which case the semicolons are optional. La última sintaxis produce un código más legible cuando las expresiones de inicialización de elementos son más largas o si quiere incluir un comentario para cada elemento.The latter syntax can result in more readable code when the element initialization expressions are longer, or when you want to include a comment for each element.

let list123 = [
    1
    2
    3 ]

Normalmente, todos los elementos de lista deben ser del mismo tipo.Normally, all list elements must be the same type. Una excepción es que una lista en la cual los elementos se han especificado para que sean de un tipo base puede tener elementos que sean de tipos derivados.An exception is that a list in which the elements are specified to be a base type can have elements that are derived types. Por lo tanto, lo siguiente es aceptable, porque tanto Button como CheckBox derivan de Control.Thus the following is acceptable, because both Button and CheckBox derive from Control.

let myControlList : Control list = [ new Button(); new CheckBox() ]

También puede definir elementos de lista usando un intervalo indicado por enteros separados por el operador de intervalo (..), tal y como se muestra en el código siguiente.You can also define list elements by using a range indicated by integers separated by the range operator (..), as shown in the following code.

let list1 = [ 1 .. 10 ]

Una lista vacía se especifica por un par de corchetes con nada entre ellos.An empty list is specified by a pair of square brackets with nothing in between them.

// An empty list.
let listEmpty = []

También puede usar una expresión de secuencia para crear una lista.You can also use a sequence expression to create a list. Vea expresiones de secuencia para obtener más información.See Sequence Expressions for more information. Por ejemplo, el código siguiente crea una lista de cuadrados de enteros, de 1 a 10.For example, the following code creates a list of squares of integers from 1 to 10.

let listOfSquares = [ for i in 1 .. 10 -> i*i ]

Operadores para trabajar con listasOperators for Working with Lists

Puede asociar elementos a una lista usando el operador :: (cons).You can attach elements to a list by using the :: (cons) operator. Si list1 es [2; 3; 4], el código siguiente crea list2 como [100; 2; 3; 4].If list1 is [2; 3; 4], the following code creates list2 as [100; 2; 3; 4].

let list2 = 100 :: list1

Para concatenar listas que tengan tipos compatibles, puede usar el operador @, como en el código siguiente.You can concatenate lists that have compatible types by using the @ operator, as in the following code. Si list1 es [2; 3; 4] y list2 es [100; 2; 3; 4], este código crea list3 como [2; 3; 4; 100; 2; 3; 4].If list1 is [2; 3; 4] and list2 is [100; 2; 3; 4], this code creates list3 as [2; 3; 4; 100; 2; 3; 4].

let list3 = list1 @ list2

Las funciones para realizar operaciones en listas están disponibles en el módulo de lista.Functions for performing operations on lists are available in the List module.

Como en F# las listas son inmutables, las operaciones de modificación generan nuevas listas en lugar de modificar las existentes.Because lists in F# are immutable, any modifying operations generate new lists instead of modifying existing lists.

Las listas F# de se implementan como listas vinculadas individualmente, lo que significa que las operaciones que tienen acceso solo al encabezado de la lista son o (1) y el acceso a los elementos es o (n).Lists in F# are implemented as singly linked lists, which means that operations that access only the head of the list are O(1), and element access is O(n).

PropiedadesProperties

El tipo de lista admite las siguientes propiedades:The list type supports the following properties:

PropiedadProperty EscribaType DESCRIPCIÓNDescription
HeadHead 'T El primer elemento.The first element.
VacíaEmpty 'T list Propiedad estática que devuelve una lista vacía del tipo apropiado.A static property that returns an empty list of the appropriate type.
VacíoIsEmpty bool true si la lista no tiene ningún elemento.true if the list has no elements.
ElementoItem 'T Elemento en el índice especificado (base cero).The element at the specified index (zero-based).
LongitudLength int Número de elementos.The number of elements.
ColaTail 'T list La lista sin el primer elemento.The list without the first element.

Los siguientes son algunos ejemplos de cómo usar estas propiedades.Following are some examples of using these properties.

let list1 = [ 1; 2; 3 ]

// Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))

Usar listasUsing Lists

Programar con listas permite realizar operaciones complejas con una pequeña cantidad de código.Programming with lists enables you to perform complex operations with a small amount of code. En esta sección se describen las operaciones comunes en las listas que son importantes para la programación funcional.This section describes common operations on lists that are important to functional programming.

Recursión con listasRecursion with Lists

Las listas están especialmente indicadas para las técnicas de programación recursiva.Lists are uniquely suited to recursive programming techniques. Tomemos una operación que deba realizarse en todos los elementos de una lista.Consider an operation that must be performed on every element of a list. Puede hacerlo recursivamente ejecutando una operación en el encabezado de la lista y, después, devolviendo la cola de la lista (que es una lista más pequeña formada por la lista original sin el primer elemento) de nuevo al siguiente nivel de recursión.You can do this recursively by operating on the head of the list and then passing the tail of the list, which is a smaller list that consists of the original list without the first element, back again to the next level of recursion.

Para escribir una función recursiva de este estilo, se usa el operador cons (::) en coincidencia de patrones, lo que permite separar el encabezado de una lista de la cola.To write such a recursive function, you use the cons operator (::) in pattern matching, which enables you to separate the head of a list from the tail.

En el ejemplo de código siguiente se muestra cómo usar la coincidencia de patrones para implementar una función recursiva que realice operaciones en una lista.The following code example shows how to use pattern matching to implement a recursive function that performs operations on a list.

let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0

El código anterior funciona bien para listas pequeñas, pero en listas mayores podría desbordar la pila.The previous code works well for small lists, but for larger lists, it could overflow the stack. El código siguiente mejora este código usando un argumento acumulador, una técnica estándar para trabajar con funciones recursivas.The following code improves on this code by using an accumulator argument, a standard technique for working with recursive functions. El uso del argumento acumulador hace que la función sea recursiva en la cola, lo que ahorra espacio en la pila.The use of the accumulator argument makes the function tail recursive, which saves stack space.

let sum list =
   let rec loop list acc =
       match list with
       | head :: tail -> loop tail (acc + head)
       | [] -> acc
   loop list 0

La función RemoveAllMultiples es una función recursiva que toma dos listas.The function RemoveAllMultiples is a recursive function that takes two lists. La primera lista contiene los números cuyos múltiplos se van a quitar, y la segunda es la lista de la que se van a quitar los números.The first list contains the numbers whose multiples will be removed, and the second list is the list from which to remove the numbers. El código del ejemplo siguiente usa esta función recursiva para eliminar de una lista todos los números que no sean primos, dejando como resultado una lista de números primos.The code in the following example uses this recursive function to eliminate all the non-prime numbers from a list, leaving a list of prime numbers as the result.

let IsPrimeMultipleTest n x =
   x = n || x % n <> 0

let rec RemoveAllMultiples listn listx =
   match listn with
   | head :: tail -> RemoveAllMultiples tail (List.filter (IsPrimeMultipleTest head) listx)
   | [] -> listx


let GetPrimesUpTo n =
    let max = int (sqrt (float n))
    RemoveAllMultiples [ 2 .. max ] [ 1 .. n ]

printfn "Primes Up To %d:\n %A" 100 (GetPrimesUpTo 100)

La salida es la siguiente:The output is as follows:

Primes Up To 100:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97]

Funciones del móduloModule Functions

El módulo de lista proporciona funciones que tienen acceso a los elementos de una lista.The List module provides functions that access the elements of a list. El elemento de encabezado es la manera más rápida y sencilla de acceder.The head element is the fastest and easiest to access. Use el encabezado de propiedad o la función de módulo List. Head.Use the property Head or the module function List.head. Puede tener acceso al final de una lista mediante la propiedad tail o la función List. tail .You can access the tail of a list by using the Tail property or the List.tail function. Para buscar un elemento por índice, use la función List. nth .To find an element by index, use the List.nth function. List.nth atraviesa la lista.List.nth traverses the list. Por lo tanto, es O (n).Therefore, it is O(n). Si su código usa List.nth con frecuencia, quizás quiera considerar la posibilidad de usar una matriz en lugar de una lista.If your code uses List.nth frequently, you might want to consider using an array instead of a list. El acceso a elementos en las matrices es O(1).Element access in arrays is O(1).

Operaciones booleanas en listasBoolean Operations on Lists

La función List. IsEmpty determina si una lista tiene elementos.The List.isEmpty function determines whether a list has any elements.

La función List. exists aplica una prueba booleana a los elementos de una lista true y devuelve si algún elemento cumple la prueba.The List.exists function applies a Boolean test to elements of a list and returns true if any element satisfies the test. List. exists2 ( es similar pero funciona en pares sucesivos de elementos de dos listas.List.exists2 is similar but operates on successive pairs of elements in two lists.

En el código siguiente se muestra cómo usar List.exists.The following code demonstrates the use of List.exists.

// Use List.exists to determine whether there is an element of a list satisfies a given Boolean expression.
// containsNumber returns true if any of the elements of the supplied list match
// the supplied number.
let containsNumber number list = List.exists (fun elem -> elem = number) list
let list0to3 = [0 .. 3]
printfn "For list %A, contains zero is %b" list0to3 (containsNumber 0 list0to3)

La salida es la siguiente:The output is as follows:

For list [0; 1; 2; 3], contains zero is true

El siguiente ejemplo muestra el uso de List.exists2.The following example demonstrates the use of List.exists2.

// Use List.exists2 to compare elements in two lists.
// isEqualElement returns true if any elements at the same position in two supplied
// lists match.
let isEqualElement list1 list2 = List.exists2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
let list1to5 = [ 1 .. 5 ]
let list5to1 = [ 5 .. -1 .. 1 ]
if (isEqualElement list1to5 list5to1) then
    printfn "Lists %A and %A have at least one equal element at the same position." list1to5 list5to1
else
    printfn "Lists %A and %A do not have an equal element at the same position." list1to5 list5to1

La salida es la siguiente:The output is as follows:

Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.

Puede usar List. ForAll si desea comprobar si todos los elementos de una lista cumplen una condición.You can use List.forall if you want to test whether all the elements of a list meet a condition.

let isAllZeroes list = List.forall (fun elem -> elem = 0.0) list
printfn "%b" (isAllZeroes [0.0; 0.0])
printfn "%b" (isAllZeroes [0.0; 1.0])

La salida es la siguiente:The output is as follows:

true
false

De forma similar, List. forall2 ( determina si todos los elementos de las posiciones correspondientes de dos listas satisfacen una expresión booleana que implica cada par de elementos.Similarly, List.forall2 determines whether all elements in the corresponding positions in two lists satisfy a Boolean expression that involves each pair of elements.

let listEqual list1 list2 = List.forall2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
printfn "%b" (listEqual [0; 1; 2] [0; 1; 2])
printfn "%b" (listEqual [0; 0; 0] [0; 1; 0])

La salida es la siguiente:The output is as follows:

true
false

Operaciones de ordenación en listasSort Operations on Lists

Las funciones List. Sort, List. sortByy List. sortWith ( ordenan las listas.The List.sort, List.sortBy, and List.sortWith functions sort lists. La función de ordenación determina cuál de estas tres funciones se usará.The sorting function determines which of these three functions to use. List.sort usa una comparación genérica predeterminada.List.sort uses default generic comparison. La comparación genérica usa operadores globales basados en la función de comparación genérica para comparar valores.Generic comparison uses global operators based on the generic compare function to compare values. Funciona de forma eficaz con una amplia variedad de tipos de elemento, como tipos numéricos simples, tuplas, registros, uniones discriminadas, listas, matrices y cualquier tipo que implemente System.IComparable.It works efficiently with a wide variety of element types, such as simple numeric types, tuples, records, discriminated unions, lists, arrays, and any type that implements System.IComparable. Para los tipos que implementan System.IComparable, la comparación genérica usa la función System.IComparable.CompareTo().For types that implement System.IComparable, generic comparison uses the System.IComparable.CompareTo() function. La comparación genérica también trabaja con cadenas, pero usa una ordenación independiente de la referencia cultural.Generic comparison also works with strings, but uses a culture-independent sorting order. La comparación genérica no se debe usar en tipos no admitidos, como los tipos de función.Generic comparison should not be used on unsupported types, such as function types. Además, el rendimiento de la comparación genérica predeterminada es mejor para tipos estructurados pequeños; para los tipos estructurados mayores que deben compararse y ordenarse con frecuencia, considere la posibilidad de implementar System.IComparable y de proporcionar una implementación eficaz del método System.IComparable.CompareTo().Also, the performance of the default generic comparison is best for small structured types; for larger structured types that need to be compared and sorted frequently, consider implementing System.IComparable and providing an efficient implementation of the System.IComparable.CompareTo() method.

List.sortBy toma una función que devuelve un valor que se usa como criterio de ordenación, y List.sortWith toma una función de comparación como argumento.List.sortBy takes a function that returns a value that is used as the sort criterion, and List.sortWith takes a comparison function as an argument. Estas dos últimas funciones son útiles cuando se trabaja con tipos que no permiten la comparación, o cuando la comparación requiere semánticas de comparación más complejas, como es el caso de las cadenas que tienen en cuenta la referencia cultural.These latter two functions are useful when you are working with types that do not support comparison, or when the comparison requires more complex comparison semantics, as in the case of culture-aware strings.

El siguiente ejemplo muestra el uso de List.sort.The following example demonstrates the use of List.sort.

let sortedList1 = List.sort [1; 4; 8; -2; 5]
printfn "%A" sortedList1

La salida es la siguiente:The output is as follows:

[-2; 1; 4; 5; 8]

El siguiente ejemplo muestra el uso de List.sortBy.The following example demonstrates the use of List.sortBy.

let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2

La salida es la siguiente:The output is as follows:

[1; -2; 4; 5; 8]

El siguiente ejemplo muestra el uso de List.sortWith.The next example demonstrates the use of List.sortWith. En este ejemplo, la función de comparación personalizada compareWidgets se usa para comparar primero un campo de un tipo personalizado, y después otro cuando los valores del primer campo son iguales.In this example, the custom comparison function compareWidgets is used to first compare one field of a custom type, and then another when the values of the first field are equal.

type Widget = { ID: int; Rev: int }

let compareWidgets widget1 widget2 =
   if widget1.ID < widget2.ID then -1 else
   if widget1.ID > widget2.ID then 1 else
   if widget1.Rev < widget2.Rev then -1 else
   if widget1.Rev > widget2.Rev then 1 else
   0

let listToCompare = [
    { ID = 92; Rev = 1 }
    { ID = 110; Rev = 1 }
    { ID = 100; Rev = 5 }
    { ID = 100; Rev = 2 }
    { ID = 92; Rev = 1 }
    ]

let sortedWidgetList = List.sortWith compareWidgets listToCompare
printfn "%A" sortedWidgetList

La salida es la siguiente:The output is as follows:

[{ID = 92;
Rev = 1;}; {ID = 92;
Rev = 1;}; {ID = 100;
Rev = 2;}; {ID = 100;
Rev = 5;}; {ID = 110;
Rev = 1;}]

Operaciones de búsqueda en listasSearch Operations on Lists

Se admiten numerosas operaciones de búsqueda en las listas.Numerous search operations are supported for lists. La más sencilla, List. Find, permite buscar el primer elemento que coincide con una condición determinada.The simplest, List.find, enables you to find the first element that matches a given condition.

El ejemplo de código siguiente muestra el uso de List.find para buscar el primer número que es divisible por 5 en una lista.The following code example demonstrates the use of List.find to find the first number that is divisible by 5 in a list.

let isDivisibleBy number elem = elem % number = 0
let result = List.find (isDivisibleBy 5) [ 1 .. 100 ]
printfn "%d " result

El resultado es 5.The result is 5.

Si los elementos se deben transformar primero, llame a List. Pick, que toma una función que devuelve una opción y busca el primer valor de opción que sea Some(x).If the elements must be transformed first, call List.pick, which takes a function that returns an option, and looks for the first option value that is Some(x). En lugar de devolver el elemento, List.pick devuelve el resultado x.Instead of returning the element, List.pick returns the result x. Si no se encuentra ningún elemento coincidente, List.pick activa System.Collections.Generic.KeyNotFoundException.If no matching element is found, List.pick throws System.Collections.Generic.KeyNotFoundException. En el código siguiente se muestra el uso de List.pick.The following code shows the use of List.pick.

let valuesList = [ ("a", 1); ("b", 2); ("c", 3) ]

let resultPick = List.pick (fun elem ->
                    match elem with
                    | (value, 2) -> Some value
                    | _ -> None) valuesList
printfn "%A" resultPick

La salida es la siguiente:The output is as follows:

"b"

Otro grupo de operaciones de búsqueda, List. tryFind y funciones relacionadas, devuelven un valor de opción.Another group of search operations, List.tryFind and related functions, return an option value. La función List.tryFind devuelve el primer elemento de una lista que cumple una condición si ese elemento existe, pero el valor de opción None si no.The List.tryFind function returns the first element of a list that satisfies a condition if such an element exists, but the option value None if not. La variación List. tryfindindex ( devuelve el índice del elemento, si se encuentra uno, en lugar del propio elemento.The variation List.tryFindIndex returns the index of the element, if one is found, rather than the element itself. Estas funciones quedan reflejadas en el código siguiente.These functions are illustrated in the following code.

let list1d = [1; 3; 7; 9; 11; 13; 15; 19; 22; 29; 36]
let isEven x = x % 2 = 0
match List.tryFind isEven list1d with
| Some value -> printfn "The first even value is %d." value
| None -> printfn "There is no even value in the list."

match List.tryFindIndex isEven list1d with
| Some value -> printfn "The first even value is at position %d." value
| None -> printfn "There is no even value in the list."

La salida es la siguiente:The output is as follows:

The first even value is 22.
The first even value is at position 8.

Operaciones aritméticas en listasArithmetic Operations on Lists

Las operaciones aritméticas comunes, como SUM y Average, se integran en el módulo List.Common arithmetic operations such as sum and average are built into the List module. Para trabajar con List. SUM, el tipo de elemento de lista debe + admitir el operador y tener un valor de cero.To work with List.sum, the list element type must support the + operator and have a zero value. Todos los tipos aritmético integrados cumplen estas condiciones.All built-in arithmetic types satisfy these conditions. Para trabajar con List. Average, el tipo de elemento debe admitir la división sin resto, lo que excluye los tipos enteros, pero permite tipos de punto flotante.To work with List.average, the element type must support division without a remainder, which excludes integral types but allows for floating point types. Las funciones List. sumBy ( y List. averageBy toman una función como parámetro, y los resultados de esta función se usan para calcular los valores de la suma o el promedio.The List.sumBy and List.averageBy functions take a function as a parameter, and this function's results are used to calculate the values for the sum or average.

En el código siguiente se muestra cómo usar List.sum, List.sumBy y List.average.The following code demonstrates the use of List.sum, List.sumBy, and List.average.

// Compute the sum of the first 10 integers by using List.sum.
let sum1 = List.sum [1 .. 10]

// Compute the sum of the squares of the elements of a list by using List.sumBy.
let sum2 = List.sumBy (fun elem -> elem*elem) [1 .. 10]

// Compute the average of the elements of a list by using List.average.
let avg1 = List.average [0.0; 1.0; 1.0; 2.0]

printfn "%f" avg1

El resultado es 1.000000The output is 1.000000.

En el código siguiente se muestra el uso de List.averageBy.The following code shows the use of List.averageBy.

let avg2 = List.averageBy (fun elem -> float elem) [1 .. 10]
printfn "%f" avg2

El resultado es 5.5The output is 5.5.

Listas y tuplasLists and Tuples

Las listas que contienen tuplas se pueden manipular con las funciones zip y unzip.Lists that contain tuples can be manipulated by zip and unzip functions. Estas funciones combinan dos listas de valores únicos en una lista de tuplas o separan una lista de tuplas en dos listas de valores únicos.These functions combine two lists of single values into one list of tuples or separate one list of tuples into two lists of single values. La función List. zip más sencilla toma dos listas de elementos únicos y genera una sola lista de pares de tupla.The simplest List.zip function takes two lists of single elements and produces a single list of tuple pairs. Otra versión, List. zip3 (, toma tres listas de elementos únicos y genera una única lista de tuplas que tienen tres elementos.Another version, List.zip3, takes three lists of single elements and produces a single list of tuples that have three elements. En el siguiente ejemplo de código se muestra el uso de List.zip.The following code example demonstrates the use of List.zip.

let list1 = [ 1; 2; 3 ]
let list2 = [ -1; -2; -3 ]
let listZip = List.zip list1 list2
printfn "%A" listZip

La salida es la siguiente:The output is as follows:

[(1, -1); (2, -2); (3; -3)]

En el siguiente ejemplo de código se muestra el uso de List.zip3.The following code example demonstrates the use of List.zip3.

let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3

La salida es la siguiente:The output is as follows:

[(1, -1, 0); (2, -2, 0); (3, -3, 0)]

Las versiones de unzip correspondientes, List. unzip y List. unzip3 (, toman listas de tuplas y devuelven listas en una tupla, donde la primera lista contiene todos los elementos que estaban en primer lugar en cada tupla y la segunda lista contiene el segundo elemento de cada uno. tupla, etc.The corresponding unzip versions, List.unzip and List.unzip3, take lists of tuples and return lists in a tuple, where the first list contains all the elements that were first in each tuple, and the second list contains the second element of each tuple, and so on.

En el ejemplo de código siguiente se muestra el uso de List. unzip.The following code example demonstrates the use of List.unzip.

let lists = List.unzip [(1,2); (3,4)]
printfn "%A" lists
printfn "%A %A" (fst lists) (snd lists)

La salida es la siguiente:The output is as follows:

([1; 3], [2; 4])
[1; 3] [2; 4]

En el ejemplo de código siguiente se muestra el uso de List. unzip3 (.The following code example demonstrates the use of List.unzip3.

let listsUnzip3 = List.unzip3 [(1,2,3); (4,5,6)]
printfn "%A" listsUnzip3

La salida es la siguiente:The output is as follows:

([1; 4], [2; 5], [3; 6])

Operar en elementos de listaOperating on List Elements

F# admite diferentes operaciones en los elementos de lista.F# supports a variety of operations on list elements. La más sencilla es List. ITER, que le permite llamar a una función en cada elemento de una lista.The simplest is List.iter, which enables you to call a function on every element of a list. Las variaciones incluyen List. iter2 (, que permite realizar una operación en elementos de dos listas, List. ITERI, que es como List.iter , a excepción de que el índice de cada elemento se pasa como argumento a la función a la que se llama para cada uno. Element y List. iteri2 (, que es una combinación de la funcionalidad de List.iter2 y. List.iteriVariations include List.iter2, which enables you to perform an operation on elements of two lists, List.iteri, which is like List.iter except that the index of each element is passed as an argument to the function that is called for each element, and List.iteri2, which is a combination of the functionality of List.iter2 and List.iteri. En el siguiente ejemplo de código se muestran estas funciones.The following code example illustrates these functions.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
List.iter (fun x -> printfn "List.iter: element is %d" x) list1
List.iteri(fun i x -> printfn "List.iteri: element %d is %d" i x) list1
List.iter2 (fun x y -> printfn "List.iter2: elements are %d %d" x y) list1 list2
List.iteri2 (fun i x y ->
                printfn "List.iteri2: element %d of list1 is %d element %d of list2 is %d"
                  i x i y)
            list1 list2

La salida es la siguiente:The output is as follows:

List.iter: element is 1
List.iter: element is 2
List.iter: element is 3
List.iteri: element 0 is 1
List.iteri: element 1 is 2
List.iteri: element 2 is 3
List.iter2: elements are 1 4
List.iter2: elements are 2 5
List.iter2: elements are 3 6
List.iteri2: element 0 of list1 is 1; element 0 of list2 is 4
List.iteri2: element 1 of list1 is 2; element 1 of list2 is 5
List.iteri2: element 2 of list1 is 3; element 2 of list2 is 6

Otra función que se usa con frecuencia que transforma elementos de lista es List. map, que permite aplicar una función a cada elemento de una lista y colocar todos los resultados en una nueva lista.Another frequently used function that transforms list elements is List.map, which enables you to apply a function to each element of a list and put all the results into a new list. List. MAP2 ( y List. map3 ( son variaciones que toman varias listas.List.map2 and List.map3 are variations that take multiple lists. También puede usar List. MAPI y List. mapi2 (si, además del elemento, la función debe pasar el índice de cada elemento.You can also use List.mapi and List.mapi2, if, in addition to the element, the function needs to be passed the index of each element. La única diferencia entre List.mapi2 y List.mapi es que List.mapi2 trabaja con dos listas.The only difference between List.mapi2 and List.mapi is that List.mapi2 works with two lists. En el ejemplo siguiente se muestra List. map.The following example illustrates List.map.

let list1 = [1; 2; 3]
let newList = List.map (fun x -> x + 1) list1
printfn "%A" newList

La salida es la siguiente:The output is as follows:

[2; 3; 4]

En el ejemplo siguiente se muestra el uso de List.map2.The following example shows the use of List.map2.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
let sumList = List.map2 (fun x y -> x + y) list1 list2
printfn "%A" sumList

La salida es la siguiente:The output is as follows:

[5; 7; 9]

En el ejemplo siguiente se muestra el uso de List.map3.The following example shows the use of List.map3.

let newList2 = List.map3 (fun x y z -> x + y + z) list1 list2 [2; 3; 4]
printfn "%A" newList2

La salida es la siguiente:The output is as follows:

[7; 10; 13]

En el ejemplo siguiente se muestra el uso de List.mapi.The following example shows the use of List.mapi.

let newListAddIndex = List.mapi (fun i x -> x + i) list1
printfn "%A" newListAddIndex

La salida es la siguiente:The output is as follows:

[1; 3; 5]

En el ejemplo siguiente se muestra el uso de List.mapi2.The following example shows the use of List.mapi2.

let listAddTimesIndex = List.mapi2 (fun i x y -> (x + y) * i) list1 list2
printfn "%A" listAddTimesIndex

La salida es la siguiente:The output is as follows:

[0; 7; 18]

List. Collect es como List.map, salvo que cada elemento genera una lista y todas estas listas se concatenan en una lista final.List.collect is like List.map, except that each element produces a list and all these lists are concatenated into a final list. En el código siguiente, cada elemento de la lista genera tres números.In the following code, each element of the list generates three numbers. Todos ellos se recopilan en una lista.These are all collected into one list.

let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList

La salida es la siguiente:The output is as follows:

[1; 2; 3; 2; 4; 6; 3; 6; 9]

También puede usar List. Filter, que toma una condición booleana y genera una nueva lista que solo consta de los elementos que satisfacen la condición especificada.You can also use List.filter, which takes a Boolean condition and produces a new list that consists only of elements that satisfy the given condition.

let evenOnlyList = List.filter (fun x -> x % 2 = 0) [1; 2; 3; 4; 5; 6]

La lista resultante es [2; 4; 6].The resulting list is [2; 4; 6].

Una combinación de asignación y filtro, List. Choose permite transformar y seleccionar elementos al mismo tiempo.A combination of map and filter, List.choose enables you to transform and select elements at the same time. List.choose aplica una función que devuelve una opción a cada elemento de una lista, y devuelve una nueva lista de resultados de elementos cuando la función devuelve el valor de opción Some.List.choose applies a function that returns an option to each element of a list, and returns a new list of the results for elements when the function returns the option value Some.

El código siguiente muestra cómo usar List.choose para seleccionar las palabras en mayúsculas de una lista de palabras.The following code demonstrates the use of List.choose to select capitalized words out of a list of words.

let listWords = [ "and"; "Rome"; "Bob"; "apple"; "zebra" ]
let isCapitalized (string1:string) = System.Char.IsUpper string1.[0]
let results = List.choose (fun elem ->
    match elem with
    | elem when isCapitalized elem -> Some(elem + "'s")
    | _ -> None) listWords
printfn "%A" results

La salida es la siguiente:The output is as follows:

["Rome's"; "Bob's"]

Operar en varias listasOperating on Multiple Lists

Las listas se pueden unir entre sí.Lists can be joined together. Para combinar dos listas en una, use List. Append.To join two lists into one, use List.append. Para combinar más de dos listas, use List. concat.To join more than two lists, use List.concat.

let list1to10 = List.append [1; 2; 3] [4; 5; 6; 7; 8; 9; 10]
let listResult = List.concat [ [1; 2; 3]; [4; 5; 6]; [7; 8; 9] ]
List.iter (fun elem -> printf "%d " elem) list1to10
printfn ""
List.iter (fun elem -> printf "%d " elem) listResult

Operaciones de plegamiento y exploraciónFold and Scan Operations

Algunas operaciones de lista implican interdependencias entre todos los elementos de lista.Some list operations involve interdependencies between all of the list elements. Las operaciones de plegamiento y de recorrido List.iter son List.map como y, en el caso de que se invoque una función en cada elemento, pero estas operaciones proporcionan un parámetro adicional denominado el acumulador que lleva información a través del cálculo.The fold and scan operations are like List.iter and List.map in that you invoke a function on each element, but these operations provide an additional parameter called the accumulator that carries information through the computation.

Use List.fold para realizar un cálculo en una lista.Use List.fold to perform a calculation on a list.

En el ejemplo de código siguiente se muestra el uso de List. Fold para realizar varias operaciones.The following code example demonstrates the use of List.fold to perform various operations.

La lista se atraviesa; el acumulador acc es un valor que va pasando mientras se realiza el cálculo.The list is traversed; the accumulator acc is a value that is passed along as the calculation proceeds. El primer argumento toma el acumulador y el elemento de lista y devuelve el resultado provisional del cálculo para ese elemento de lista.The first argument takes the accumulator and the list element, and returns the interim result of the calculation for that list element. El segundo argumento es el valor inicial del acumulador.The second argument is the initial value of the accumulator.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 3 ] (sumList [ 1 .. 3 ])

// The following example computes the average of a list.
let averageList list = (List.fold (fun acc elem -> acc + float elem) 0.0 list / float list.Length)

// The following example computes the standard deviation of a list.
// The standard deviation is computed by taking the square root of the
// sum of the variances, which are the differences between each value
// and the average.
let stdDevList list =
    let avg = averageList list
    sqrt (List.fold (fun acc elem -> acc + (float elem - avg) ** 2.0 ) 0.0 list / float list.Length)

let testList listTest =
    printfn "List %A average: %f stddev: %f" listTest (averageList listTest) (stdDevList listTest)

testList [1; 1; 1]
testList [1; 2; 1]
testList [1; 2; 3]

// List.fold is the same as to List.iter when the accumulator is not used.
let printList list = List.fold (fun acc elem -> printfn "%A" elem) () list
printList [0.0; 1.0; 2.5; 5.1 ]

// The following example uses List.fold to reverse a list.
// The accumulator starts out as the empty list, and the function uses the cons operator
// to add each successive element to the head of the accumulator list, resulting in a
// reversed form of the list.
let reverseList list = List.fold (fun acc elem -> elem::acc) [] list
printfn "%A" (reverseList [1 .. 10])

Las versiones de estas funciones que tienen un dígito en el nombre de la función operan en más de una lista.The versions of these functions that have a digit in the function name operate on more than one list. Por ejemplo, List. fold2 ( realiza cálculos en dos listas.For example, List.fold2 performs computations on two lists.

El siguiente ejemplo muestra el uso de List.fold2.The following example demonstrates the use of List.fold2.

// Use List.fold2 to perform computations over two lists (of equal size) at the same time.
// Example: Sum the greater element at each list position.
let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->
                                              acc + max elem1 elem2) 0 list1 list2

let sum = sumGreatest [1; 2; 3] [3; 2; 1]
printfn "The sum of the greater of each pair of elements in the two lists is %d." sum

List.foldy List. Scan difiere en List.fold que devuelve el valor final del parámetro adicional, pero List.scan devuelve la lista de los valores intermedios (junto con el valor final) del parámetro adicional.List.fold and List.scan differ in that List.fold returns the final value of the extra parameter, but List.scan returns the list of the intermediate values (along with the final value) of the extra parameter.

Cada una de estas funciones incluye una variación inversa, por ejemplo, List. foldBack, que difiere en el orden en el que se recorre la lista y el orden de los argumentos.Each of these functions includes a reverse variation, for example, List.foldBack, which differs in the order in which the list is traversed and the order of the arguments. Además, List.fold y List.foldBack tienen variaciones, List. fold2 ( y List. foldBack2 (, que toman dos listas de la misma longitud.Also, List.fold and List.foldBack have variations, List.fold2 and List.foldBack2, that take two lists of equal length. La función que se ejecuta en cada elemento puede usar los elementos correspondientes de ambas listas para realizar alguna acción.The function that executes on each element can use corresponding elements of both lists to perform some action. Los tipos de elemento de las dos listas pueden ser diferentes, como en el ejemplo siguiente, en el que una lista contiene los importes de las transacciones de una cuenta bancaria y la otra lista contiene el tipo de transacción: ingreso o retirada.The element types of the two lists can be different, as in the following example, in which one list contains transaction amounts for a bank account, and the other list contains the type of transaction: deposit or withdrawal.

// Discriminated union type that encodes the transaction type.
type Transaction =
    | Deposit
    | Withdrawal

let transactionTypes = [Deposit; Deposit; Withdrawal]
let transactionAmounts = [100.00; 1000.00; 95.00 ]
let initialBalance = 200.00

// Use fold2 to perform a calculation on the list to update the account balance.
let endingBalance = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2)
                                initialBalance
                                transactionTypes
                                transactionAmounts
printfn "%f" endingBalance

Para un cálculo como la suma, List.fold y List.foldBack tiene el mismo efecto porque el resultado no depende del orden del recorrido.For a calculation like summation, List.fold and List.foldBack have the same effect because the result does not depend on the order of traversal. En el ejemplo siguientes, se usa List.foldBack para sumar los elementos de una lista.In the following example, List.foldBack is used to add the elements in a list.

let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0
printfn "%d" (sumListBack [1; 2; 3])

// For a calculation in which the order of traversal is important, fold and foldBack have different
// results. For example, replacing fold with foldBack in the listReverse function
// produces a function that copies the list, rather than reversing it.
let copyList list = List.foldBack (fun elem acc -> elem::acc) list []
printfn "%A" (copyList [1 .. 10])

El ejemplo siguiente vuelve al ejemplo de la cuenta bancaria.The following example returns to the bank account example. Esta vez se agrega un nuevo tipo de transacción: un cálculo de interés.This time a new transaction type is added: an interest calculation. El saldo final depende ahora del orden de las transacciones.The ending balance now depends on the order of transactions.

type Transaction2 =
    | Deposit
    | Withdrawal
    | Interest

let transactionTypes2 = [Deposit; Deposit; Withdrawal; Interest]
let transactionAmounts2 = [100.00; 1000.00; 95.00; 0.05 / 12.0 ]
let initialBalance2 = 200.00

// Because fold2 processes the lists by starting at the head element,
// the interest is calculated last, on the balance of 1205.00.
let endingBalance2 = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                initialBalance2
                                transactionTypes2
                                transactionAmounts2
printfn "%f" endingBalance2


// Because foldBack2 processes the lists by starting at end of the list,
// the interest is calculated first, on the balance of only 200.00.
let endingBalance3 = List.foldBack2 (fun elem1 elem2 acc ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                transactionTypes2
                                transactionAmounts2
                                initialBalance2
printfn "%f" endingBalance3

La lista de funciones . reduce es algo List.fold parecido List.scana y, salvo que, en lugar de pasar un acumulador independiente, List.reduce toma una función que toma dos argumentos del tipo de elemento en lugar de uno solo y uno de ellos. los argumentos actúan como el acumulador, lo que significa que almacena el resultado intermedio del cálculo.The function List.reduce is somewhat like List.fold and List.scan, except that instead of passing around a separate accumulator, List.reduce takes a function that takes two arguments of the element type instead of just one, and one of those arguments acts as the accumulator, meaning that it stores the intermediate result of the computation. List.reduce comienza por operar en los dos primeros elementos y, después, usa el resultado de la operación con el siguiente elemento.List.reduce starts by operating on the first two list elements, and then uses the result of the operation along with the next element. Como no hay un acumulador diferente que tenga su propio tipo, se puede usar List.reduce en lugar de List.fold solo cuando el acumulador y el elemento sean del mismo tipo.Because there is not a separate accumulator that has its own type, List.reduce can be used in place of List.fold only when the accumulator and the element type have the same type. En el código siguiente se muestra cómo usar List.reduce.The following code demonstrates the use of List.reduce. List.reduce activa una excepción si la lista proporciona no tiene elementos.List.reduce throws an exception if the list provided has no elements.

En el código siguiente, en la primera llamada a la expresión lambda se proporcionan los argumentos 2 y 4, y devuelve 6; en la siguiente llamada se proporcionan los argumentos 6 y 10, por lo que el resultado es 16.In the following code, the first call to the lambda expression is given the arguments 2 and 4, and returns 6, and the next call is given the arguments 6 and 10, so the result is 16.

let sumAList list =
    try
        List.reduce (fun acc elem -> acc + elem) list
    with
       | :? System.ArgumentException as exc -> 0

let resultSum = sumAList [2; 4; 10]
printfn "%d " resultSum

Convertir entre listas y otros tipos de coleccionesConverting Between Lists and Other Collection Types

El módulo List proporciona funciones para convertir desde y hacia secuencias y matrices.The List module provides functions for converting to and from both sequences and arrays. Para convertir a o desde una secuencia, use List. toseq ( o List. ofSeq.To convert to or from a sequence, use List.toSeq or List.ofSeq. Para realizar la conversión a o desde una matriz, use List. toArray o List. myArray.To convert to or from an array, use List.toArray or List.ofArray.

Otras operacionesAdditional Operations

Para obtener información sobre las operaciones adicionales de las listas, vea el módulo de referencia de la biblioteca Collections. List.For information about additional operations on lists, see the library reference topic Collections.List Module.

Vea tambiénSee also