如何在Swift中将字典值数组打印成一个很好的字符串

时间:2016-11-19 12:29:23

标签: ios arrays swift dictionary

我有一组routine个对象,定义为:

struct Routine {
    let routineName: String
    let routineExercisesAndSets: [String: Int]
}

let routines: [Routine] = {
    let firstRoutine = Routine(routineName: "Legs", routineExercisesAndSets: ["Squats":4,"Lunges":4,"Calf Raises":4])

    let secondRoutine = Routine(routineName: "Chest", routineExercisesAndSets: ["Bench Press":4,"Press Ups":4,"Flyes":4,"Inclined Bench Press":4])

    let thirdRoutine = Routine(routineName: "Arms", routineExercisesAndSets: ["Bicep Curls":4,"Hammer Curls":4,"Preacher Curls":4,"Tricep Extension":4,"Tricep Dips":4])

    return [firstRoutine, secondRoutine, thirdRoutine]
}()

我试图将routineExercisesAndSets数组作为详细文本返回到UITableViewCell,并且在使用array.description函数时,我在tableView中得到了这个结果

this result in the tableView

我的问题是,如何迭代例程对象并打印出一个看起来像“漂亮”的格式化字符串:

"Calf Raises x 4, Squats x 4, Lunges x 4..."

我可以使用以下代码在新行上打印出各个键,值对:

for i in routines{
    for (key, value) in (i.routineExercisesAndSets)! {
        print("\(key) x \(String(value))")
    }
}

产生:

Calf Raises x 4 Squats x 4 Lunges x 4 Bench Press x 4 Press Ups x 4 Flyes x 4 Inclined Bench Press x 4 Tricep Extension x 4 Tricep Dips x 4 Preacher Curls x 4 Hammer Curls x 4 Bicep Curls x 4

但我希望按照父对象对它们进行分组,以便在同一行上显示常规练习,使其看起来像示例"Calf Raises x 4, Squats x 4, Lunges x 4..."

2 个答案:

答案 0 :(得分:3)

您可以进行链式mapjoined操作,以构建描述给定练习的练习字典的单个String。 E.g。

for routine in routines {
    print("Routine:", routine.routineName)
    print("--------------")
    print(routine.routineExercisesAndSets
        .map { $0 + " x \($1)" }
        .joined(separator: ", "))
    print()
}
/* Routine: Legs
   --------------
   Calf Raises x 4, Squats x 4, Lunges x 4

   Routine: Chest
   --------------
   Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4

   Routine: Arms
   --------------
   Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4 

                   */

此外,不是在每次使用时显式执行这些“演示”转换,而是将它们实现为description的计算Routine属性的返回,作为让Routine的一部分符合CustomStringConvertible

extension Routine: CustomStringConvertible {
    var description: String {
        return routineName + ":\n" + routineExercisesAndSets
            .map { $0 + " x \($1)" }
            .joined(separator: ", ")
    }
}

for routine in routines {
    print(routine) /* uses Routine:s implementation of 'CustomStringConvertible',
                      the computed property 'description`, specifically           */
    print()
}
/* Legs:
   Calf Raises x 4, Squats x 4, Lunges x 4

   Chest:
   Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4

   Arms:
   Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4

                   */

根据下面的评论,似乎routineName的{​​{1}}和routineExercisesAndSets属性是可选项。如果是这种情况,您自然需要在访问它们(可能存在的)值之前处理它们。例如,如果两个属性中的任何一个是Routine,则返回空description,否则,返回组合的例程名称和详细描述(如上面的非可选示例中所做的那样):

nil

答案 1 :(得分:1)

首先让我们RoutineCustomStringConvertible

一致
extension Routine: CustomStringConvertible {
    var description: String {
        return routineExercisesAndSets.map { $0 + " x " + $1.description }.joined(separator: ", ")
    }
}

现在你可以轻松编写

routines.forEach { print($0) }

结果

Calf Raises x 4, Squats x 4, Lunges x 4
Bench Press x 4, Press Ups x 4, Flyes x 4, Inclined Bench Press x 4
Tricep Extension x 4, Tricep Dips x 4, Preacher Curls x 4, Hammer Curls x 4, Bicep Curls x 4

或者给出UITableViewCell ...

let cell: UITableViewCell = ...
let routine: Routine = ...
cell.detailTextLabel?.text = routine.description