Сортировка массива возвращает неправильное значение - PullRequest
1 голос
/ 10 июля 2019

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

Для этого я использовал методы .last() и .first().

func closestNumbers(_ column: [String], value: Int) {                           
    // Gets the closest element in array to userInput
    let userInput = value

    let rangeA = column

    let left = rangeA.last(where: { $0  <=  String(userInput)})!      // last element that is less or equal to userInput
    let right = rangeA.first(where: { $0 >= String(userInput)})!    // first element that is bigger or the same as userInput


    print(left, userInput, right)
    // prints   left <= userInput >= right
}

ПРИМЕР: Если userInput будет 450 в массиве [100, 200, ...., 1000].

Печать должна вернуться (400, 450, 500)

Однако он возвращает 1000, 450, 500.

Хотя я чувствую, что логика верна.

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Вы пытаетесь сравнить строки , а не числа здесь:

let left = rangeA.last(where: { $0  <=  String(userInput)})!
let right = rangeA.first(where: { $0 >= String(userInput)})!

Это означает, что они будут сравниваться в словарном порядке или лексикографически . В порядке словаря, 1000 предшествует 450, поэтому оно «меньше» 450. И поскольку 1000 является последним элементом в массиве, он выбирается как последний, который меньше 450.

Вместо этого следует преобразовать элементы массива в Int и сравнить вместо Int s:

let left = rangeA.last(where: { Int($0)!  <=  userInput})!
let right = rangeA.first(where: { Int($0)! >= userInput})! 

На самом деле, почему бы просто не сделать тип параметра [Int] вместо [String]?

func closestNumbers(_ column: [Int], value: Int) {

Тогда вам вообще не нужно никаких преобразований.

Обратите внимание, что это будет работать, только если rangeA отсортировано. Если сортировка rangeA не гарантируется, вы должны сначала отсортировать ее.

0 голосов
/ 10 июля 2019

Решение состоит в том, чтобы не использовать String, а Int вместо

func closestNumbers(_ column: [Int], value: Int) -> (Int?, Int, Int?) {                           
    return (column.last(where: { $0  <  value}), value, column.first(where: { $0 > value}))
}

let arr = Array(0...20).map { $0 * 50 }

print(closestNumbers(arr, value: 450))
...