Группировка элементов близко друг к другу

Я пытаюсь найти надежный способ группировки элементов, чтобы значение было следующим в списке.

Данные у меня такие

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 последовательно

Я надеюсь это имеет смысл.

Если я правильно понимаю, это простая композиция из трех отдельных процессов. 1) Разделите все элементы, находящиеся под или над -13.0. 2) Отсортируйте обе стороны по их значениям X. 3) Разделите элементы, чтобы сформировать ряды последовательных значений X. Я правильно понимаю?

Alexander 27.05.2019 20:19

Почему -13? Вы пытаетесь сгруппировать точки на графике, которые очень близки? В этом случае -13 изменится в зависимости от значений других точек на графике, верно? Возможно, вам придется использовать какой-то другой алгоритм для достижения этой группировки. Боюсь, в таком случае все будет не так просто, как вы думаете.

adev 27.05.2019 21:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я нашел простое решение для достижения этой цели с помощью функции уменьшения. Если у кого-то есть другие более чистые, более краткие подходы, я весь внимание.

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
}

Используйте метод уменьшить (в:_:) и перечислите элементы массива. Если значение 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)]]

Другие вопросы по теме