0
votes

Firstindex: de: dans un tableau d'objets

J'ai cette classe: xxx

puis j'ai une gamme d'objets de cette classe.

Maintenant, je veux analyser ce tableau et trouver l'objet de < CODE> VATEATEMESTAMP Classe avec la valeur minimale.

Supposons que le tableau ait 3 éléments

  1. ollement1 (valeur = 12, horodatage = 2)
  2. ollement2 (valeur = 5, horodatage = 3)
  3. Element3 (valeur = 10, horodatage = 4)

    et xxx

    maintenant, je veux trouver l'élément qui a la valeur minimale.

    Je suppose que cela fonctionnerait xxx

    mais la deuxième ligne me donne cette erreur

    Étiquette d'argumentation incorrecte dans l'appel (avoir 'de:', attendue 'Où:')

    Des idées?


1 commentaires

ValêtreMestamp est une sorte de nom non claire ("valeur" a beaucoup de significations différentes dans le monde rapide. L'une concerne la valeur VS Ref Sémantique, une autre concerne les valeurs vs types, et je suis sûr qu'il y a Suite). Pourrais-je suggérer horodatagevalue ? Bien que ce n'est même pas un nom précis non plus, car la «valeur» est très générale, mais que seuls les magasins double. Peut-être horodatageDouble ? Ou peut-être que vous pourriez le rendre générique: horodatagevalue


3 Réponses :


2
votes

firstindex (de:) ne fonctionne pas car je présume que votre classe n'est pas conforme à équatable .

C'est pourquoi il est attendu de votre part d'utiliser firstindex (où:) pour ce cas.

Également dans le code ci-dessous, vous n'obtenez pas d'objet, vous obtenez la valeur, donc min est le type de double? pas valeur estapetamp? : xxx

Vous pouvez obtenir l'index min avec les éléments suivants avec où: < / p> xxx

références:

https://developer.apple.com/documentation/swift/array/2994720-firstindex https://developer.apple.com/documentation/swift/array/2994722- firstindex


4 commentaires

Xcode me donne une erreur disant opérateur binaire '==' ne peut pas être appliqué aux opérandes de type 'Double' et '_' N'oubliez pas que la valeur est double.


Cela fonctionne bien pour moi, je me demande pourquoi il est dit == ne peut pas être appliqué au double et _ let minindex = myarray.firstindex (où: {$ 0.value == min}) min est un type de double de toute façon. C'est étrange


Pas besoin de cartographier les valeurs que vous pouvez utiliser Max méthode sur les indices de collecte. si let index = myarray.indices.min (par: {myarray [$ 0] .Value


Cela fait que 2 passe dans le tableau, ce qui est inutile. Voir ma réponse pour plus de détails.



4
votes

firstindex: de: recherche le premier élément qui est égal à l'argument fourni. Mais vous ne cherchez pas un élément égal à celui-ci, vous recherchez une propriété dont la propriété est égale. Vous devez donc utiliser et fournir une fonction pour cela à la place: xxx

Vous pouvez également rendre votre classe conforme à comparable et appeler min sur elle directement: xxx

Notez que s'il est possible d'avoir deux objets avec la même valeur , vous pouvez Besoin d'ajuster les fonctions pour déterminer lequel est "moins" dans ce cas.


3 commentaires

Cette implémentation code que l'égalité et la comparabilité de valeur de valeur uniquement sur la valeur , qui pourrait ne pas être souhaitable. Deux cas avec des horodatages différents seraient considérés comme égaux. Cela pourrait être intentionnel, sinon ce n'est peut-être pas, mais il convient de souligner.


@Alexander Oui, j'ai mentionné qu'à la fin.


@Johnmontgomery Oh, j'ai trouvé ce genre de crête de claire. Je comprends cela maintenant, mais pour l'exhaustivité et le bien des autres, pourriez-vous élaborer sur votre réponse?



0
votes

La cause première ici est que firstindex (de: _) est défini uniquement sur collection où élément: Equatetable . Votre type n'est pas accompagné, de sorte que cette méthode ne vous soit pas mise à votre disposition, jusqu'à ce que vous le permettriez de la conformité.

Cependant, votre problème peut être résolu plus élégamment résolu en utilisant Array.Enuméated () et array.min (par: _) :

Si vous n'avez besoin que de élément, vous pouvez faire ceci: xxx

Si vous n'avez besoin que de l'index, vous pouvez le faire: xxx

si Vous voulez les deux, vous pouvez le faire: xxx

tous les trois de ces extraits obtiennent la réponse à l'aide d'une seule passe à travers la matrice, ce qui les rend deux fois plus rapides que le " Trouvez le min, puis trouvez son indice "Approche".


6 commentaires

Cela vous donne l'élément non pas l'index.


Enuméré vous donne le décalage, pas l'index. Cela fonctionnerait pour un tableau mais pas pour une tranche de celui-ci. Vous devriez toujours travailler avec les indices de collecte. si let index = myarray.indices.min (par: {myarray [$ 0] .Value


@Leodabus cela dépend de ce que OP essaie d'atteindre exactement. Mais si des indices basés sur zéro sont souhaités pour des tranches, le meilleur moyen de le faire est de remplacer array.enumé.enumé () avec zip (array.indices, tableau)


Pas besoin de zip si vous avez l'index, vous avez également accès à l'élément. BTW C'était juste une note pour clarifier cette compensation, ce n'est pas la même chose que l'index. Si vous aimez vraiment cette section zip collection d'extension {FUNC EnumeratedIndices (Corps: (((((index: index, élément: élément)) Jette -> ()) Retéhrows {Essayez zip (indices, auto). }


@Leodabus "Si vous avez l'index, vous avez accès à l'élément aussi" dans O (1)?


Si vous êtes tous préoccupés par la vitesse, vous pouvez étendre la langue comme je l'ai montré dans le commentaire ci-dessus à l'aide de l'approche ZIP ou utilisez l'approche standard avec une boucle de base et une collection formidex (après:) méthode: Collection d'extension {FUNC EnumeratedIndIndIndIndIndIndIndIndes (Corps: ((Index: Index, élément: Elément)) Jouette -> ()) Retéhrows {Var Index = Self.Startindex for Element in Self {Essayez le corps ((index, élément)) Formindex ( après: & index)}}}