问题描述
我正在尝试提供ArrayList中项目的摘要(顺序很重要)。基本上,我正在制定一个包含两种不同类型的活动(培训和评估)的锻炼计划。然后,在将每个培训/评估添加到计划之后,我将提供该计划的摘要。
我拥有的结构类似于:
exercisePlan: [
{TRAINING OBJECT},{TRAINING OBJECT},{ASSESSMENT OBJECT},{TRAINING OBJECT}
]
我想要做的是用以下格式总结一下:
2 x Training,1 x Assessment,1 x Training
,它将显示在片段的TextView中。因此,我将使用任意长的字符串,详细说明锻炼计划的结构和顺序。
我曾尝试使用HashMap或普通的ArrayList进行调查,但似乎很杂乱,因此我正在寻找一种更简洁的方法(也许是MutableList)。预先感谢!
解决方法
ArrayList只是MutableList的一种特定类型。通常最好使用纯列表,因为可变性会使代码使用起来更加复杂并保持健壮性。
我将创建一个类列表,该类包装一个动作以及执行该动作的连续次数。
enum class Activity {
Training,Assessment
}
data class SummaryPlanStep(val activity: Activity,val consecutiveTimes: Int) {
override fun toString() = "$consecutiveTimes x $activity"
}
如果要从摘要开始,则可以创建摘要,然后将其转换为活动的简单列表,如下所示:
val summary: List<SummaryPlanStep> = listOf(
SummaryPlanStep(Activity.Training,2),SummaryPlanStep(Activity.Assessment,1),SummaryPlanStep(Activity.Training,)
val plan: List<Activity> = summary.flatMap { List(it.consecutiveTimes) { _ -> it.activity } }
如果您想以其他方式进行操作,那么它会涉及更多,因为我认为没有内置的方法可以对连续重复的元素进行分组。您可以为此编写一个函数。
fun <T> List<T>.groupConsecutiveDuplicates(): List<Pair<T,Int>> {
if (isEmpty()) return emptyList()
val outList = mutableListOf<Pair<T,Int>>()
var current = first() to 1
for (i in 1 until size) {
val item = this[i]
current = if (item == current.first)
current.first to (current.second + 1)
else {
outList.add(current)
item to 1
}
}
outList.add(current)
return outList
}
val plan: List<Activity> = listOf(
Activity.Training,Activity.Training,Activity.Assessment,Activity.Training
)
val summary: List<SummaryPlanStep> = plan.groupConsecutiveDuplicates().map { SummaryPlanStep(it.first,it.second) }
,
这是我目前为我准备的工作:
if (exercisePlanSummary.isNotEmpty() && exercisePlanSummary[exercisePlanSummary.size - 1].containsKey(trainingAssessment)) {
exercisePlanSummary[exercisePlanSummary.size - 1][trainingAssessment] = exercisePlanSummary[exercisePlanSummary.size - 1][trainingAssessment]!! + 1
} else {
exercisePlanSummary.add(hashMapOf(trainingAssessment to 1))
}
var textToDisplay = ""
exercisePlanSummary.forEach {
textToDisplay = if (textToDisplay.isNotEmpty()) {
textToDisplay.plus(",${it.values.toList()[0]} x ${it.keys.toList()[0].capitalize()}")
} else {
textToDisplay.plus("${it.values.toList()[0]} x ${it.keys.toList()[0].capitalize()}")
}
}
其中trainingAssessment
是String
或"training"
的{{1}}。 "assessment"
是exercisePlanSummary
。
@ Tenfour04上面写的内容可能更合适,并且是实现此目的的更简洁的方法。但是我的方法很简单。