按另一个数组中的元素对结构数组进行排序(快速)

时间:2018-11-06 03:20:04

标签: arrays swift sorting

好,所以我想根据另一个数组对一个数组进行排序。好吧,这听起来似乎很令人困惑,所以让我解释一下。

好的,让我们以一个有关杂货店购物的应用程序为例。好的,所以我有一个像这样的数组:

var fruitsArray = [String:Int]()

假设数组的值为

[apple:32, banana:45, grape:7, strawberry:23]

好吧,首先,我用Int对该数组进行降序排序,这样得出

[banana:45 apple:32, strawberry:23, grape:7]

好的。但是现在我想要一个购物清单数组,该数组的每个元素都包含食物数组。因此,让我们做一个Struct ...

struct List {
    var name:String = ""
    var items:[String] = [""]

    init(name: String, items: [String) {
        self.name = name
        self.items = items
    }
}

,然后是List ...

的数组
var shoppingLists = [List]()

最后,让我们将一些元素添加到shoppingLists ...

[List(name: List 1, items: [banana, pizza, watermelon, apple]),
List(name: List 2, items: [cookie, water, grape, apple]),
List(name: List 3, items: [apple, strawberry, banana, cheese]),
List(name: List 4, items: [apple, strawberry, grape, watermelon])]

好的,这有点困难。我想通过查看shoppingLists中的items数组并将它们与shoppingLists进行比较来对fruitsArray进行排序。让我告诉您我希望最终产品是什么,然后我将解释原因。

sortedShoppingList = 
[List(name: List 3, items: [apple, strawberry, banana, cheese]),
List(name: List 4, items: [apple, strawberry, grape, watermelon]),
List(name: List 1, items: [banana, pizza, watermelon, apple]),
List(name: List 2, items: [cookie, water, grape, apple])]

好吧,为什么在世界上这样排序?让我们逐个地介绍它。因此列表3位于顶部,因为它包含来自fruitsArray的3个元素。现在您可能会说列表4也包含来自fruitsArray的3个元素,是的,但是列表3包含来自fruitsArray的“排名”较高的元素。列表3和4都包含[apple, strawberry],但是列表3包含banana,而列表4包含grapeBanana胜过“ grape”,因此首先进入列表3。接下来,列表1紧随列表4之后,因为它包含[apple, banana],其“排名”高于[apple, grape]在清单2中。

好的,我真的希望那不会造成混淆。如果您有任何疑问或需要我澄清,请询问!非常感谢您阅读本文,希望您能帮助我。

2 个答案:

答案 0 :(得分:1)

为解决该问题,我使用了一种积分系统,可以像这样为购物车中的每个列表计算积分;

List 1, items: banana + pizza + watermelon + apple = 77   
List 2, items: cookie + water + grape + apple = 30    
List 3, items: apple + strawberry + banana + cheese = 100    
List 4, items: apple+ strawberry + grape + watermelon = 62

然后,如果我们对获得的点结果进行排序;

List 3, items: [apple + strawberry + banana] = 100   
List 1, items: [banana + apple] = 77   
List 4, items: [apple + strawberry + grape] = 62   
List 2, items: [grape + apple] = 30

但这不是解决方案。我们需要考虑每个列表中水果的数量,因此我们将点乘以匹配fruitArray的项目,就像这样;

List 3, items: [apple + strawberry + banana] = 100 * 3 = 300  
List 1, items: [banana + apple] = 77 * 2 = 154  
List 4, items: [apple + strawberry + grape] = 62  * 3 = 186  
List 2, items: [grape + apple] = 30 * 2 = 78

现在,如果我们排序可以得到正确的结果:

List 3, point = 300   
List 4, point = 186  
List 1, point = 154  
List 2, point = 78

代码如下:

import UIKit

struct List {
    var id:Int = -1
    var items:[String] = [""]
    var point = 0

    init(id: Int, items: [String]) {
        self.id = id
        self.items = items
    }
}

var result = [List]()
var fruitsArray = ["banana":45, "apple":32, "strawberry":23, "grape":7]
var shoppingLists = [List(id: 1, items: ["banana", "pizza", "watermelon", "apple"]),
                     List(id: 2, items: ["cookie", "water", "grape", "apple"]),
                     List(id: 3, items: ["apple", "strawberry", "banana", "cheese"]),
                     List(id: 4, items: ["apple", "strawberry", "grape", "watermelon"])]


func calcPoints(lists: [List]){
    for list in lists{
        for item in list.items{
            let index = fruitsArray.index(forKey: item)
            if index != nil{
                shoppingLists[list.id - 1].point = shoppingLists[list.id - 1].point + fruitsArray[index!].value
            }
            else{
                shoppingLists[list.id - 1].items = shoppingLists[list.id - 1].items.filter { $0 != item }
            }
        }
        shoppingLists[list.id - 1].point = shoppingLists[list.id - 1].point * shoppingLists[list.id - 1].items.count
    }
}

calcPoints(lists: shoppingLists)
result = shoppingLists.sorted(by: { $0.point > $1.point })
print(result)

答案 1 :(得分:1)

使用reduce函数计算每个List的排名,并使用sorted方法对数组进行排序。

let sorted = shoppingLists.sorted { list1, list2 in
    let a = list1.items.reduce(0) { sum, nextItem in
        return sum + (fruitsArray[nextItem] ?? 0)
    }
    let b = list2.items.reduce(0) { sum, nextItem in
        return sum + (fruitsArray[nextItem] ?? 0)
    }
    return a > b
}