Пользовательская модель данных Swift reduce tuple array

#swift #dictionary #filter #tuples #reduce

#swift #словарь #Фильтр #кортежи #уменьшить

Вопрос:

Я пытаюсь уменьшить компоненты значения «y» для каждого аналогичного значения «x» в этом массиве CustomDataModel и вернуть массив CustomDataModel (или просто массив кортежей [(Double, Double)].

Мои знания о Swift в лучшем случае рудиментарны, и попытка использовать функцию цепочки следующим образом сокращает по всему массиву, а не по значению «x». Я не уверен, как я могу ограничить функцию reduce только подобными значениями.

 let reducedArray = yValues.filter( {$0.x == $0.x}).map({$0.y}).reduce(0,  )

  

вышеупомянутая функция уменьшает все значения y, не относящиеся к x .
Ниже приведена модель и некоторые фиктивные данные:

 struct CustomDataModel {
    var x : Double
    var y : Double
}

let yValues: [CustomDataModel] = [
CustomDataModel(x: 0.0, y: 10.0),
CustomDataModel(x: 1.0, y: 5.0),
CustomDataModel(x: 1.0, y: 12.5),
CustomDataModel(x: 1.0, y: 14.5),
CustomDataModel(x: 1.0, y: 18.45),
CustomDataModel(x: 5.0, y: 11.4),
CustomDataModel(x: 5.0, y: 9.4),
CustomDataModel(x: 5.0, y: 18.4),
CustomDataModel(x: 5.0, y: 5.0),
CustomDataModel(x: 9.0, y: 7.6),
CustomDataModel(x: 9.0, y: 13.5),
CustomDataModel(x: 9.0, y: 18.5),
CustomDataModel(x: 9.0, y: 17.6),
CustomDataModel(x: 9.0, y: 14.3),
CustomDataModel(x: 14.0, y: 19.6),
CustomDataModel(x: 14.0, y: 17.8),
CustomDataModel(x: 14.0, y: 20.1),
CustomDataModel(x: 14.0, y: 21.5),
CustomDataModel(x: 14.0, y: 23.4),
]
  

В идеале результат, который у меня был бы, выглядел бы следующим образом:

 print(reducedArray)
//[(0.0, 10.0), (1.0, 50.45), (5.0, 44.2), (9.0, 71.5), (14.0, 102.4)]
  

Ответ №1:

Вам нужно сгруппировать yValues массив по x в Dictionary . И сопоставляет значения с y , а затем выполняет reduce . Вот как:

 let reducedArray = Dictionary(grouping: yValues, by: .x).mapValues({ $0.map(.y).reduce(0,  ) })
print(reducedArray)
  

Обновление: Если вам требуется, чтобы результат был в [(Double, Double)] формате, вы можете сопоставить приведенный выше результат с кортежами.

Комментарии:

1. Спасибо Франкенштейну за быстрый ответ. Создание словаря может сработать, поскольку я могу его отсортировать, но есть ли в любом случае необходимость поддерживать структуру кортежей [(double, double)], поскольку приложение требует, чтобы я мог выполнять итерации по индексу.

2. Я думаю, что я понял это, выполнив следующее: let mapped = reducedArray.map{$0}.sorted(by: <)