我发现自己遇到了麻烦,必须将数组分为两个数组。一个仅包含价格,另一个仅包含描述。
例如:
var startingArray = ["apple", "30.00", "pizza", "2.00"]
结果应该是:
var firstArray = ["apple", "pizza"]
var secondArray = ["30.00", "2.00"]
Swift 4.2
有没有办法达到这个结果? 预先感谢
答案 0 :(得分:1)
您不想要这种结果。
apple
与30.00
在一起。 pizza
与2.00
在一起。
如果使用这两个数组,则如果更改顺序,则删除一个,则需要对第二个数组执行相同的操作。
使用字典数组代替
let startingArray = ["apple", "30.00", "pizza", "2.00"]
var final: [[String: String]] = []
for i in stride(from: 0, to: startingArray.count, by: 2) {
let name = startingArray[i]
let price = startingArray[i+1]
final.append(["name": name, "price": price])
}
print("final: \(final)")
输出:
$> [["name": "apple", "price": "30.00"], ["name": "pizza", "price": "2.00"]]
然后,您可以对最终数组进行操作:
let first: [String: String] = final[0]
let firstName = first[name]
let firstPrice = first[price]
您也可以使用元组,但是更好的方法是使用自定义struct / class来表示它。
struct Grocery {
let name: String
let price: Double
init(name: String, priceStr: String) {
self.name = name
self.price = Double(priceStr) ?? 0
}
}
let startingArray = ["apple", "30.00", "pizza", "2.00"]
var groceries = [Grocery]()
for i in stride(from: 0, to: startingArray.count, by: 2) {
let name = startingArray[i]
let price = startingArray[i+1]
let grocery = Grocery(name: name, priceStr: price)
groceries.append(grocery)
}
print("groceries: \(groceries)")
输出:
$> groceries: [Grocery(name: "apple", price: 30.0), Grocery(name: "pizza", price: 2.0)]
然后,您可以对最终数组进行操作:
let first: Grocery = groceries[0]
let firstName = first.name
let firstPrice = first.price
注意:我使用Double作为价格,但是如果您希望将其保留为String
,则取决于您。
答案 1 :(得分:0)
您可以尝试如下操作:
extension Array {
func separate() -> (odd: [Element], even: [Element]) {
return self.reduce(into: (odd: [], even: [])) { (acc, element) in
if (acc.even.count + acc.odd.count) % 2 == 0 {
acc.odd.append(element)
} else {
acc.even.append(element)
}
}
}
}
let startingArray = ["apple", "30.00", "pizza", "2.00"]
let (firstArray, secondArray) = startingArray.separate()
print(firstArray) // ["apple", "pizza"]
print(secondArray) // ["30.00", "2.00"]
使用此方法,您可以将数组元素组合成字典:
extension Array where Element: Hashable {
func dictionaryWithOddEvenRule(uniquingKeysWith combine: (Element, Element) throws -> Element) rethrows -> [Element: Element] {
let (keys, values) = self.separate()
let sequence = zip(keys, values)
return try Dictionary(sequence, uniquingKeysWith: combine)
}
}
甚至在一般情况下:
extension Array {
func dictionaryWithOddEvenRule<K, V>(keysTransform: (Element) throws -> K, valueTransform: (Element) throws -> V, uniquingKeysWith combine: (V, V) throws -> V) rethrows -> [K: V] where K: Hashable {
let (keys, values) = self.separate()
let sequence = zip(try keys.map(keysTransform), try values.map(valueTransform))
return try Dictionary.init(sequence, uniquingKeysWith: combine)
}
}
例如:
enum ExampleError: Error {
case cantParseDouble
}
do {
let result: [String: Double] = try startingArray.dictionaryWithOddEvenRule(
keysTransform: { $0 }, // Transform between array element type to dictionary key type
valueTransform: {
// Transform between array element type to dictionary value type
if let double = Double($0) {
return double
} else {
throw ExampleError.cantParseDouble
}
},
uniquingKeysWith: {
($0 + $1)/2 // Handle situation when two identical keys exist
}
)
print(result) // Handle result
} catch let error {
print(error) // Handle error
}
答案 2 :(得分:0)
您可以使用forEach
功能来实现此目的。
在声明了startingArray之后,将另外两个Strings和Doubles数组声明为:
var doubleArray = [String]()
var stringArray = [String]()
然后使用forEach
来启动array来分隔元素并相应地添加如下内容:
startingArray.forEach { (element) in
if let _ = Double(element) {
doubleArray.append(element)
} else {
stringArray.append(element)
}
}
打印阵列时,结果将显示为单独:
print(doubleArray)
print(stringArray)
答案 3 :(得分:0)
尝试使用
步幅: 推荐
let f1 = stride(from: 1, to: startingArray.count, by: 2).map({ startingArray[$0] })
let f2 = stride(from: 0, to: startingArray.count, by: 2).map({ startingArray[$0] })
过滤器:
let f1 = startingArray.filter({ Double($0) != nil })
let f2 = startingArray.filter({ !f1.contains($0) })
答案 4 :(得分:0)
您可以这样操作:
var startingArray = ["apple", "30.00", "pizza", "2.00"]
var firstArray: [String] = []
var secondArray: [String] = []
for str in startingArray {
if let _ = Double(str) {
firstArray.append(str)
} else {
secondArray.append(str)
}
}
print(firstArray) //["30.00", "2.00"]
print(secondArray) //["apple", "pizza"]
但是正如Larme所建议的那样,您最好在方法上更加面向对象,并使用例如structs
struct Fruit {
let name: String
let price: Double
}
var startingArray = ["apple", "30.00", "pizza", "2.00"]
let zipped = zip(startingArray, startingArray.dropFirst())
var fruitArray = [Fruit]()
for couple in zipped {
let name = couple.0
if let price = Double(couple.1) {
let fruit = Fruit(name: name, price: price)
fruitArray.append(fruit)
}
}