Additionner les valeurs d'un Array d'objets

Bonjour à tous,
je travaille sur une application de budget.
je possède un tableau d’objets comme suit :

struct Cell {
let valeur:String
let date:String
}

var arrayCellule:[Cellule]

avec ce tableau je créé une liste que l’utilisateur peut incrémenter en rajoutant une valeur.

Ce que je souhaiterais c’est d’additionner toutes les valeurs de ce tableau d’objet (sans la date donc), et d’ajouter le résultat à une nouvelle variable qui affichera la somme à l’utilisateur (avec la possibilité d’additionner ou soustraire, et la somme se mettra à jour automatiquement).
Sauf que la je sèche…
Si quelqu’un aurait une solution cela m’aiderai beaucoup :slight_smile: .

Une boucle réglera ton problème. Par contre je ne comprends pas pourquoi ta valeur numérique est stockée dans un String ?

De même que la date d’ailleurs, il y a un type de données en SWIFT pour stocker et faire des calculs sur les dates.

Salut,

Pour ma part j’ai fait ceci pour résoudre ton problème dans ta configuration.

Après tu aurais plus simple de configurer tes valeurs directement en Int plutôt que du String (tu peux faire la conversion après avec une propriété calculée) et pour la date tu as aussi une valeur Date() en Swift mais je dois admettre que elle est difficile à manipulée.

Tu as surement beaucoup plus pratique après, quelque un de plus doué ici pourra surement le proposé :stuck_out_tongue:

C’est brutal ta solution … Je n’ai pas Xcode sous la main, je ferais un petit exemple ce soir.

1 « J'aime »

Environnement UIKit ou SwiftUI ?

Merci @East je vois ou tu veux en venir, oui ça m’a l’air de marcher, et je dois dire que je n’avais pas le raisonnement :sweat_smile:.
@Draken alors j’ai mis la valeur en String pour une question de facilité étant donné que je récupère cette dernière de l’utilisateur par un TextField.
Et la date en String c’est simplement pour l’affichage, je récupère une date par le Date() et je passe par le formatter pour la récupérer en String.
Après ce n’est peut être pas la bonne méthode mais c’est celle qui m’a semblé le plus simple.
Et je suis sur SwiftUI.
Merci déjà de vos réponses je vais aller essayer ça dans la soirée.

Bonjour,

Ma contribution, testée rapidement dans un Playground:

import Foundation

struct Cell {
    let valeur: String
    let date: String
}

let cell = Cell(valeur: "2", date: "555")

let arrayCellule = [cell, cell, cell, cell, cell, cell, cell]

var arrayCelluleSumOfValues: Int {
    arrayCellule.reduce(0) { (temporarySum, cell) in
        temporarySum + (Int(cell.valeur) ?? 0)
    }
}

let total = arrayCelluleSumOfValues

Cordialement,
Nicolas

Je n’ai pas testé, mais ça devrais fonctionner :

struct cellString {
  let valeur : String
  let date   : String
}

func total (liste:[cellString]) -> Double {
  var somme = 0.0
  
  for depense in liste {
    if let valeur = Double(depense.valeur) {
      somme += valeur
    }
  }
  return somme
}

C’est une simple boucle. Le test de validité et la conversion du String en Double se fait, avec l’opérateur Double() qui retourne un Double?

Pourquoi des Doubles ? Tu parles d’une application de budget plus haut. Il faut des variables flottantes pour contenir des prix genre : « Super Big Mac Bacon, triple fromage à 11,99 € »


EDIT : Si le tableau passé en paramètre est vide, la fonction retourne 0, ce qui n’est pas forcément une bonne chose. Pour éviter ça, la fonction peut retourner un Double? contenant la valeur nil, en cas de tableau vide.

func total (liste:[cellString]) -> Double? {
  var somme = 0.0
  
  // Sécurité anti-tableau vide
  if liste.count == 0 {
    return nil
  }
  
  for depense in liste {
    if let valeur = Double(depense.valeur) {
      somme += valeur
    }
  }
  return somme
}
2 « J'aime »

Ok j’admet je me suis cassé la tête pour rien avec ma solution :o

J’ai réfléchis mais je ne comprend pas très bien à quoi sert la fonction .reduce clairement :sweat_smile: (désolé si c’est évident)

Alors déjà, merci à tous pour vos réponses car cela m’a bien éclairé.
@Draken ta solution est si évidente et c’est exactement ce dont j’avais besoin, par contre oui tu as raison je vais plutôt utiliser des Float ça sera plus cohérent.
En attendant merci à vous je vais pouvoir continuer à avancer.

Magnifique concision ! En parfait écho du pseudo « ristretto »… J’ai dans Books le livre d’Apple sur Swift, il y a bien dedans un seul exemple de .reduce() mais ce n’est expliqué développé nulle part dans le texte, et je ne connaissais pas ; où as-tu trouvé ce truc splendide ?

Bonjour,
J’aime bien cette concision et cette élégance, même si en revenant sur un morceau de code après plusieurs mois, c’est parfois moins clair qu’une simple itération…
Trouvé il y a un bout de temps dans un article qui expliquait les 3 fonctions filter, map et reduce !

ÉDIT : par exemple ici

La question posée dans ce fil m’a semblé un bon point d’application.
Nicolas

Le fonctionnement de reduce est pourtant bien expliqué dans la doc Apple. Et l’exemple montré est justement l’addition de toutes les valeurs d’un tableau.

https://developer.apple.com/documentation/swift/array/2298686-reduce

J’ai appris son existence en regardant tous les opérateurs utilisables sur les tableaux.

Je ne l’ai pas utilisé dans ce post, car je trouve la syntaxe bien complexe pour un novice, là où une boucle est plus parlante.

On est bien d’accord !!!

Oui, tu as raison, mais ce matin, en me servant de la zone de recherche sur le site de la documentation d’Apple, je ne l’ai pas trouvé; non plus — malgré un exemple donné à propos d’autre chose — dans le book sur Swift 5.3 publié par Apple que j’ai dans Books. Peut-être les serveurs Apple étaient-ils trop occupés ce matin ? J’ai réessayé cet après-midi, bien documenté, tu avais raison, comme toujours d’ailleurs, je le reconnais — j’ai pris l’habitude d’avoir souvent tort.

C’est vrai, tu as raison, c’est tout à fait décourageant au début, d’ailleurs tout ce qui a trait aux closures et aux raccourcis d’écriture qu’elles permettent. Et ça n’est pas forcément pratique avant d’en avoir tâté suffisamment, ni à utiliser, ni même à relire. Mais là, ç’a m’a enthousiasmé, parce que j’ai trouvé ça intuitif pour une fois, par contre, si j’avais répondu, moi, j’aurais écrit une boucle qui n’aurait pas marché car j’aurais sans doute fait une majestueuse faute d’inattention, j’aurais trouvé inutile de tester, je ne l’aurais pas vu, et je serais déjà en train de te dire oui, tu as raison, ça ne marche pas, je m’excuse.
" Encore une occasion de la fermer pour ceux qui feraient mieux de ne pas l’ouvrir " (Pierre Dac)

Bonjour,
Il me semble que dans le cours de Maxime sur la programmation en Swift, dans la partie sur les closures, il y avait 3 vidéos d’utilisation des closures dans les tableaux, dont au moins une qui utilisait reduce.
A+

Comme quoi il faut sans arrêt revenir sur les cours… Je vais voir ça tout de suite ! Merci !

Eh oui, j’ai vu ça. Maxime dit bien qu’il se sert peu de reduce d’ailleurs, mais c’est sans doute la réminiscence d’avoir suivi ce cours qui m’a permis de reconnaître, comprendre et alors d’apprécier l’écriture sans boucle explicite mais avec valeur par défaut de l’ami ristretto. :smiley: