Деление массива двойников - PullRequest
0 голосов
/ 18 марта 2019

У меня есть массив парных символов:

var dates: [Double] = [1542412800000,
    1542499200000,
    1543017600000,
    1543708800000,
    1544659200000,
    1547164800000,
    1550880000000]

(да, это на самом деле даты и время). То, что я хочу, это преобразовать его в массив процентов. Например, если у меня есть массив [5, 20, 25], я хочу выводить [0,20, 0,8, 1], проценты от текущих значений. Я закончил с:

let percentages: [Double] = dates
    .map{$0 - dates.first!}
    .map{$0/dates.last!}
percentages.forEach{ it in
    print(it)
}

Но вывод:

0.0
5.5710306406685235e-05
0.00038997214484679665
0.0008356545961002785
0.0014484679665738162
0.003064066852367688
0.005459610027855153

Второе значение странное. Как это решить?

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

Вы можете сделать это так:

let dates: [Double] = [1542412800000,
                       1542499200000,
                       1543017600000,
                       1543708800000,
                       1544659200000,
                       1547164800000,
                       1550880000000]

let sorted = dates.sorted()

guard let first = sorted.first,
    let last = sorted.last,
    last != first
    else {
    fatalError()
}

let denominator = last - first

let percentages = sorted.map { ($0 - first)/denominator }

print(percentages) //[0.0, 0.01020408163265306, 0.07142857142857142, 0.15306122448979592, 0.2653061224489796, 0.5612244897959183, 1.0]
2 голосов
/ 18 марта 2019

При делении каждого значения на последнее значение в последнем операторе map вы игнорируете тот факт, что все уже вычтено первым значением.

Чтобы исправить это, вы должны разделить на диапазонзначений (разница между максимальным и минимальным значениями).

Если ваш массив отсортирован, это будет:

guard let maxValue = dates.last, let minValue = dates.first else {
    return
}
let percentages = dates
    .map {$0 - minValue}
    .map {$0 / (maxValue - minValue)}

Это нормализует все значения так, что первое значениеравно 0, а последнее значение равно 1, а все остальное находится между.

Если вы не хотите нормализовать первое значение до 0 (но оставляете все в диапазоне от 0 до 1), вы можете пропустить шаг вычитания:

let percentages = dates.map {$0 / maxValue}

Если ваш массив не отсортирован, вы можете использовать функции .min() и .max() вашего массива:

guard let maxValue = dates.max(), let minValue = dates.min() else {
    return
}
1 голос
/ 18 марта 2019

Используя ваш стиль кода, вы должны использовать что-то вроде этого:

var dates: [Double] = [1542412800000,
                       1542499200000,
                       1543017600000,
                       1543708800000,
                       1544659200000,
                       1547164800000,
                       1550880000000]

let intermediate: [Double] = dates
    .map{$0 - dates.first!}
    let percentages = intermediate
    .map{$0/intermediate.last!}
percentages.forEach{ it in
    print(it)
}

Реальная проблема в том, что вы делите каждый элемент на «начальное» максимальное значение (не смещенное на минимальное значение).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...