suzuki sport programación precio lenguaje apple swift

sport - Usa una función para encontrar elementos comunes en dos secuencias en Swift



swift apple (7)

Estoy intentando completar el ejercicio en la página 46 del nuevo libro de Apple "El lenguaje de programación Swift". Da el siguiente código:

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool { for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { return true } } } return false } anyCommonElements([1, 2, 3], [3])

El ejercicio consiste en cambiar la función para que se devuelvan todos los elementos que tienen ambas secuencias. Para ello intenté usar el siguiente código:

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> T.GeneratorType[] { var toReturn = T.GeneratorType[]() for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { toReturn.append(lhsItem) } } } return toReturn } anyCommonElements([1, 2, 3], [3])

Pero en la línea 2, aparece el error: No se pudo encontrar el ''subíndice'' del miembro

¿Cuál es la razón de este error y cuál es la mejor solución para este problema?


Aunque esta pregunta ha sido respondida, y la pregunta original era sobre trabajar con arreglos genéricos, hay una manera de usar Set y mejorar la base de conocimientos de . Todavía quiero publicarlo.

El Set clases swift contiene estos cuatro métodos:

Set.union(sequence:) Set.subtract(sequence:) Set.intersect(sequence:) Set.exclusiveOr(sequence:)

que se documentan aquí: https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_Set_Structure/index.html

Puedes convertir dos matrices en conjuntos y usar estos métodos:

let array1 = [1, 2, 3] let array2 = [3, 4] let set1 = Set<Int>(array1) let set2 = Set<Int>(array2) let union = set1.union(set2) // [2, 3, 1, 4] let subtract = set1.subtract(set2) // [2, 1] let intersect = set1.intersect(set2) // [3] let exclusiveOr = set1.exclusiveOr(set2) // [2, 4, 1]

Edición 1:

Como mencionó Martin R en un comentario, el tipo de Set<T> tiene que heredar el protocolo Hashable , que es ligeramente más restrictivo que Equatable . Y también el orden de los elementos no se conserva, por lo tanto, ¡considere la relevancia de los elementos ordenados!


Desde Swift 3, el protocolo del generador se renombra como protocolo iterador : (enlace a la propuesta de github)

Por lo tanto, la función debe ser escrita:

func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element] where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element { var common: [T.Iterator.Element] = [] for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { common.append(lhsItem) } } } return common }


El problema fue definir el valor de retorno como una matriz para que fuera posible agregarle un elemento.

func anyCommonElements<T, U where T:SequenceType, U:SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element >(lhs: T, rhs: U) -> Array <T.Generator.Element> { var result = Array <T.Generator.Element>(); for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { result.append(lhsItem); } } } return result; } print(anyCommonElements([1,3,7,9,6,8],rhs:[4,6,8]));


La forma más limpia de resolver esto en Swift 3 es usar la función de filtro de la siguiente manera:

func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element] where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element { return lhs.filter { rhs.contains($0) } }


La respuesta aceptada ya no es válida para la última versión de Swift. Aquí hay una actualización que es compatible con la versión 3.0.1, que han simplificado cómo hacer una matriz genérica.

func showCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element] where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element { var result:[T.Iterator.Element] = [] for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { result.append(lhsItem) } } } return result }

Puedes probar el código con los siguientes comandos:

showCommonElements([1, 2, 3, 4, 5], [4, 7, 3]) showCommonElements(["apple", "banana", "orange", "peach"], ["orange", "pear", "apple"])


Pude hacer que funcionara al hacer que el valor de retorno fuera un Array de T.GeneratorType.Element.

func anyCommonElements <T, U where T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, rhs: U) -> Array<T.Generator.Element> { var toReturn = Array<T.Generator.Element>() for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { toReturn.append(lhsItem) } } } return toReturn } anyCommonElements([1, 2, 3], [3])


Tuve errores de compilación con las dos soluciones anteriores. Estoy ejecutando la guía del iBook en el patio de juegos de Xcode 6.01. Tuve constantes quejas del compilador sobre las declaraciones de arreglos que encontré aquí, así que asumo que los carteles pueden estar usando una versión anterior de swift. Si me equivoco, sería genial saberlo.

Para las declaraciones de matriz, he encontrado que

var thingList : [ThingType] = []

ha trabajado consistentemente, así que solía ir con eso, abandonar

var thing[],thing[]() // gave compiler errors/warnings

Mi entorno nunca pudo resolver una cosa llamada T.GeneratorType [.Element]

La solución que encontré para este experimento es

func anyCommonElements <T, U where T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, rhs: U) -> [T.Generator.Element] { var returnValue: [T.Generator.Element] = [] for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { returnValue.append(lhsItem) } } } return returnValue } let commonNumberList = anyCommonElements([1, 2, 3,4,5,6,7,8], [2,3,9,14,8,21]) println("common Numbers = /(commonNumberList)") let commonStringList = anyCommonElements(["a","b","c"],["d","e","f","c","b"]) println("common Strings = /(commonStringList)")

El texto del tutorial realmente no me preparó adecuadamente para resolver los experimentos sin mucha lectura adicional. Gracias a todos los que están aquí por contribuir con sus soluciones, realmente me ha ayudado a obtener una excelente introducción a Swift.