使用多个动态else-if语句对对象进行排序



考虑到我们有以下内容:

typealias Fruit = String
typealias Count = Int
struct Smoothie {
let uuid: String
let fruits: [Fruit: Count]
}
let smoothies: [Smoothie] = ...

给定用户设置的条件数组:

let conditions: [Fruit] = ...

条件数组中的索引最低,我们认为它最重要的是用于排序。

我想对奶昔数组进行排序,以便首先出现conditions数组中包含最多水果(Count)的奶昔

如果一个水果没有出现在fruits字典中,我们认为它的计数为0。

例如:

let fruitsA = ["Apple": 3, "Mango": 4, "Pear": 8, "Cherry": 1, "Banana": 2]
let smoothieA = Smoothie(uuid: "smoothie_a", fruits: fruitsA)
let fruitsB = ["Apple": 10, "Mango": 9, "Grapes": 8, "Cherry": 9]
let smoothieB = Smoothie(uuid: "smoothie_b", fruits: fruitsB)
let fruitsC = ["Apple": 23, "Kiwi": 4, "Pear": 1, "Cherry": 17, "Banana": 8]
let smoothieC = Smoothie(uuid: "smoothie_c", fruits: fruitsC)
let fruitsD = ["Apple": 1, "Orange": 6, "Pear": 8]
let smoothieD = Smoothie(uuid: "smoothie_d", fruits: fruitsD)
let conditions: [Fruit] = ["Apple", "Banana", "Cherry"]

应返回以下内容:

let sortedSmoothies = [smoothieC, smoothieB, smoothieA, smoothieD]

因为我们首先按苹果排序,然后按香蕉排序,再按樱桃计数。

如果我知道它将永远是关于苹果,香蕉和苹果的;Cherry,我可以做以下事情,它就会起作用:

let sortedSmoothies = smoothies.sorted {
if $0.fruits["Apple"] != $1.fruits["Apple"] {
return $0.fruits["Apple"] > $1.fruits["Apple"]
} else if $0.fruits["Banana"] != $1.fruits["Banana"] {
return $0.fruits["Banana"] > $1.fruits["Banana"]
} else {
return $0.fruits["Cherry"] > $1.fruits["Cherry"]
}
}

但在我的情况下,我不知道用户将在条件数组中选择哪些水果(以及有多少)进行过滤。

有人知道如何sort这个吗?

谢谢!

let sorted = [smoothieA, smoothieB, smoothieC, smoothieD].sorted { (a, b) in
for condition in conditions {
let aAmount = a.fruits[condition] ?? 0
let bAmount = b.fruits[condition] ?? 0
if aAmount == bAmount {
continue
}
return aAmount > bAmount
}
return true
}

请记住,对于您的样本数据;苹果;没有任何值相等的奶昔,任何测试都会返回相同的顺序。但是,你可以用一些更有趣的数字来测试,这些数字的奶昔含有相同数量的水果:

let fruitsA = ["Apple": 10, "Mango": 4, "Pear": 8, "Cherry": 20, "Banana": 2]
let smoothieA = Smoothie(uuid: "smoothie_a", fruits: fruitsA)
let fruitsB = ["Apple": 10, "Mango": 9, "Grapes": 8, "Cherry": 9, "Banana": 2]
let smoothieB = Smoothie(uuid: "smoothie_b", fruits: fruitsB)
let fruitsC = ["Apple": 23, "Kiwi": 4, "Pear": 1, "Cherry": 17, "Banana": 8]
let smoothieC = Smoothie(uuid: "smoothie_c", fruits: fruitsC)
let fruitsD = ["Apple": 1, "Orange": 6, "Pear": 8]
let smoothieD = Smoothie(uuid: "smoothie_d", fruits: fruitsD)

您可以创建一个水果数组的数组——String[][],您可以将其称为FruitsArr。你还可以创建一个水果数组或列表,可以容纳用户放入的水果数量

这都是松散的术语,因为swift语法并不熟悉。抱歉,看到太多Java语法可能会让您感到困惑。不过,这种逻辑是普遍的。

for (int i = 0; i < fruits.length; i++){ 
/*fruits is our imaginary array of user-input fruits. This is sorting the arrays one by one by each fruit in fruits*/
String[] mostFruit; //fill it with zeroes or something.
for (int j = 0; j < FruitsArr.length; j++){
String[] thisFruit = FruitsArr[j]l
if (thisFruit[i] > mostFruit[i]){mostFruit = thisFruit;}
}
}

这检验了一个问题:thisFruit中索引i处的值是否大于mostFruit中索引i处的值?如果是,则mostFruit变为thisFruit。具有至少1个果实的第一个thisFruit变为mostFruit;0。然后比较变得更加简单。

你的循环将继续通过水果1、水果2、水果3和用户放入的其他水果。它将根据每个阵列检查每个水果:

水果1:

这个水果有超过0个水果1吗?

(下一篇)

这种水果比目前的大多数水果含有更多的这种水果吗?

(下一篇)

这种水果比目前的大多数水果含有更多的这种水果吗?

因此,它继续通过其余的水果阵列和其余的水果。

相关内容

  • 没有找到相关文章

最新更新