将元素分组在一起

时间:2019-05-27 18:02:30

标签: ios arrays swift

我试图找出一种将元素分组在一起的可靠方法,即值在列表中是下一个。

我的数据是这个

let values = [
    ChartDataEntry(x: 0.0, y: -13.0),
    ChartDataEntry(x: 1.0, y: -13.0),
    ChartDataEntry(x: 2.0, y: 0.68),
    ChartDataEntry(x: 3.0, y: -13.0),
    ChartDataEntry(x: 4.0, y: 1.7),
    ChartDataEntry(x: 5.0, y: 0.5),
    ChartDataEntry(x: 6.0, y: 10.0)
]

我正在尝试对其进行分组,因此更像这样

let values = [
    [
        ChartDataEntry(x: 0.0, y: -13.0),
        ChartDataEntry(x: 1.0, y: -13.0),
        ChartDataEntry(x: 3.0, y: -13.0)
    ],
    [
        ChartDataEntry(x: 2.0, y: 0.68)
    ],
    [
        ChartDataEntry(x: 4.0, y: 1.7),
        ChartDataEntry(x: 5.0, y: 0.5),
        ChartDataEntry(x: 6.0, y: -10.0)
    ]
]

基本上,我要实现的分组是x元素的值大于-13.0且元素小于-13的元素并在一起。棘手的部分是按x值分组。

目标是将彼此相邻的x值分组。

x:2.0紧随3.0,但它是-13,因此它不属于同一组,但是如果您查看4.0、5.0和6.0,它们的值都大于连续-13

我希望这是有道理的。

2 个答案:

答案 0 :(得分:0)

我发现实现此目标的简单解决方案是使用reduce函数。如果有人有其他更简洁的清洁方法,我将不知所措。

let grouped = values.filter({ $0.y != -13 }).reduce([[ChartDataEntry]]()) { result, item in
    var result = result
    if let lastX = result.last?.last?.x, item.x - 1.0 == lastX {
        let lastIndex = result.count - 1
         result[lastIndex].append(item)
    } else {
        result.append([item])
    }
    return result
}

答案 1 :(得分:0)

使用reduce(into:_:)方法并枚举数组元素。如果ChartDataEntry y的值小于-13.0,请获取其元素小于或等于-13.0的数组索引,并将ChartDataEntry对象附加到该子数组。如果找不到,则子数组包含与当前ChartDataEntry对象相邻的x值的ChartDataEntry对象,并将其追加到子数组。如果两个条件都失败,则使用ChartDataEntry对象添加一个新的子数组。

let result = values.reduce(into: [[ChartDataEntry]]()) { (result, chart) in
    if chart.y <= -13.0, let index = result.firstIndex(where: { $0.contains(where: { $0.y <= -13.0 }) }) {
        result[index].append(chart)
    } else if let index = result.firstIndex(where: { $0.contains(where: { $0.y > -13.0 && $0.x.advanced(by: 1) == chart.x }) }) {
        result[index].append(chart)
    } else {
        result.append([chart])
    }
}
print(result)

//[[ChartDataEntry(x: 0.0, y: -13.0), ChartDataEntry(x: 1.0, y: -13.0), ChartDataEntry(x: 3.0, y: -13.0)],
//[ChartDataEntry(x: 2.0, y: 0.68)],
//[ChartDataEntry(x: 4.0, y: 1.7), ChartDataEntry(x: 5.0, y: 0.5), ChartDataEntry(x: 6.0, y: 10.0)]]