有没有更好的方法来创建数组的索引?

时间:2017-07-22 12:43:15

标签: arrays swift iteration

我编写了一个方法,将变量rank添加到结构数组中。 数组friutsArray的创建方式与函数makeFriuts()类似。之后,数据被排序,根据这一点,每个项目分别获得rank索引。

最后我需要FriutsWithRank结构。 但我想知道是否有更好,更有效的方法。甚至可以跳过整个Friuts结构:

struct Friuts {
    var name: String
    var price: Double
}

struct FriutsWithRank {
    var name: String
    var price: Double
    var rank: Int
}

var friutsArray = [Friuts]()

func makeFriuts() {
    friutsArray.append(Friuts(name: "mango", price: 1.2))
    friutsArray.append(Friuts(name: "banana", price: 0.79))
    friutsArray.append(Friuts(name: "orange", price: 2.2))
}

func makeFriutsWithRank(data: [Friuts]) -> [FriutsWithRank] {

    let dataSorted = data.sorted { $1.price < $0.price }

    var datatoappend = [FriutsWithRank]()

    var i = 0
    dataSorted.forEach { fruit in
        i += 1
        let name = fruit.name
        let price = fruit.price
        let rank = i

        let result = FriutsWithRank(name: name, price: price, rank: rank)

        datatoappend.append(result)
    }
    return datatoappend
}

let friutsArrayWithRank = makeFriutsWithRank(data: friutsArray) 

更有效,我的意思不一定是更少的代码。我认为现在使用两次迭代创建了两个数组。是否可以跳过整个Fruits结构并只使用一个结构和一个迭代?

3 个答案:

答案 0 :(得分:2)

我已对您的代码进行了一些修改,请阅读内联评论。没有更多优化,但肯定更具可读性。

// Typo fixed + it is a single Fruit, not Fruits
struct Fruit {
    var name: String
    var price: Double
}


struct FruitsWithRank {
    // You already have a variable holding name and price, Friut
    // Lets just reuse Fruit object
    var fruit: Fruits
    var rank: Int
}

var fruits = [Fruit]()

func makeFruits() {
    fruits.append(Fruit(name: "mango", price: 1.2))
    fruits.append(Fruit(name: "banana", price: 0.79))
    fruits.append(Fruit(name: "orange", price: 2.2))
}

func makeFruitsWithRank(data: [Fruits]) -> [FruitsWithRank] {

    let dataSorted = data.sorted { $1.price < $0.price }
    var datatoappend = [FruitsWithRank]()
    // Use `enumerated` to get index and the object straight away
    for (index, fruit) in dataSorted.enumerated() {
        // Just init your `FruitsWithRank` with the fruit and the index
        let rankedFruit = FruitsWithRank(fruit: fruit, rank: index)
        // Add to your array
        datatoappend.append(rankedFruit)
    } 

    return datatoappend
}

let fruitsWithRank = makeFruitsWithRank(data: fruitsArray) 

修改 在您的问题编辑后,我已经应用了一些更改。如果您需要FruitsWithRank具有名称和价格,您只需创建名称和价格tuples,然后立即创建一个数组,无需任何循环或追加。您可以省略makeFruitsWithRank函数,并在元组数组上直接排序,枚举和创建类型。

struct FruitsWithRank {
    var rank: Int
    var name: String
    var price: Double
}

let rankedFruits: [FruitsWithRank] = [
        (name: "mango", price: 1.2), 
        (name: "banana", price: 0.79), 
        (name: "orange", price: 2.2)]
        .sorted { $0.price < $1.price }
        .enumerated()
        .map({ return FruitsWithRank(rank: $0 + 1, name: $1.name, price: $1.price) })

答案 1 :(得分:1)

最后,这不比你的代码更有效,但它更紧​​凑:

func makeFriutsWithRank(data: [Friuts]) -> [FriutsWithRank] {

    let dataMapped = data.sorted { $1.price < $0.price }
        .enumerated()
        .map { FriutsWithRank(name: $1.name, price: $1.price, rank: $0 + 1) }

    return dataMapped
}

答案 2 :(得分:0)

拥有Struct真的很难吗?因为您已经排序,所以索引可以作为排名。