1

I made up a method to add a variable rankto an array of structs. The array friutsArrayis created like in the function makeFriuts(). After that, the data gets sorted and according to this, every item gets a rank, respectively index.

In the end I need the FriutsWithRankstruct like it is. But I´m wondering if there is a better, more effective way to to that. Maybe by even skipping the whole Friuts struct:

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) 

With more effective i mean not necessarily less code. I think the two arrays are now created with two iterations. Is it possible to skip the whole Fruits struct and work just with one struct and one iteration?.

2
  • I forgot to mention, that in the end, I need the FriutsWithRankstruct like it is. Could skip the Friuts struct if possible. But definitely more readable with you suggestion. Thanks. Commented Jul 22, 2017 at 13:26
  • edited my answer. Commented Jul 22, 2017 at 14:28

3 Answers 3

2

I have applied some modification on your code, please read the inline comments. Not much more optimised, but more readable for sure.

// 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) 

EDIT: Following the edits of your question, i have applied some changes. If you need FruitsWithRank having name and price, you can just create tuples with name and price, and create an array straight away without any loops or appends. You can omit the makeFruitsWithRank function, and sort, enumerate and create your types straight on the tuple array.

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) })
Sign up to request clarification or add additional context in comments.

Comments

1

In the end this isn't much more efficient than your code, but it is more compact:

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
}

Comments

0

Is it really necassary to have Struct? Because you already have sorted, the index can serve as rank.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.