あなたは値型のアプローチに固執する(とidentifier
が一意でないことを考える:それ以外の場合は、簡単な抽出と置換ロジック用の辞書を使用することを検討してください)場合は、に変異関数を書くことができます[Instruments]
配列を所有する型で、配列内の(最初の)Instrument
インスタンスを見つけて、指定されたクロージャを使用してそれを変更します。例えば。 (改善のおかげ@Hamish!):
struct Instrument {
let identifier: String
var changeThis: Int
init(_ identifier: String, _ changeThis: Int) {
self.identifier = identifier
self.changeThis = changeThis
}
}
struct Foo {
var instruments: [Instrument]
@discardableResult // do not necessarily make use of the return result (no warning if not)
mutating func updateInstrument(forFirst identifier: String,
using mutate: (inout Instrument) ->()) -> Bool {
if let idx = instruments.indices
.first(where: { instruments[$0].identifier == identifier }) {
// mutate this instrument (in-place) using supplied closure
mutate(&instruments[idx])
return true // replacement successful
}
return false // didn't find such an instrument
}
}
使用例:@Owen:s answerに示すよう
var foo = Foo(instruments:
[Instrument("a", 1), Instrument("b", 2),
Instrument("c", 3), Instrument("b", 4)])
// make use of result of call
if foo.updateInstrument(forFirst: "b", using: { $0.changeThis = 42 }) {
print("Successfully mutated an instrument")
} // Successfully mutated an instrument
// just attempt mutate and discard the result
foo.updateInstrument(forFirst: "c", using: { $0.changeThis = 99 })
print(foo.instruments)
/* [Instrument(identifier: "a", changeThis: 1),
Instrument(identifier: "b", changeThis: 42),
Instrument(identifier: "c", changeThis: 99),
Instrument(identifier: "b", changeThis: 4)] */
、素子上の特定の述語のための最初のインデックスを見つけるためにもすっきりアプローチ配列のindex(where:)
メソッドを使用しています(前述のようにindices.first(where:)
ではなく)。完全な例でindex(where:)
アプローチを用いて、上記単にFoo
のupdateInstrument(forFirst:using)
方法で
if let idx = instruments
.index(where: { $0.identifier == identifier }) { ...
と
if let idx = instruments.indices
.first(where: { instruments[$0].identifier == identifier }) { ...
を交換に対応します。我々はさらに、単一の行に(可能性)の交換やboolean型の戻りを実行するためにOptional
のmap
機能を適用することにより、updateInstrument(forFirst:using)
方法を凝縮でき
:
struct Foo {
var instruments: [Instrument]
@discardableResult
mutating func updateInstrument(forFirst identifier: String,
using mutate: (inout Instrument) ->()) -> Bool {
return instruments
.index(where: { $0.identifier == identifier })
.map { mutate(&instruments[$0]) } != nil
}
}
'filter(_ :)'と 'first'ではなく' first(where:) 'を使うことができます。 – Hamish
構造体は値型です。プロパティを変更したら、アイテムを配列に戻す必要があります。しかし、フレームワークと戦わないでください!参照型が必要な場合は、クラスを使用します。 – vadian
これを見てください:http://stackoverflow.com/a/26375105/312312 – Lefteris