如何改编词典';在swift中阅读的s值? 编辑问题:如何调整词典的价值观,以便在swift中阅读?

如何改编词典';在swift中阅读的s值? 编辑问题:如何调整词典的价值观,以便在swift中阅读?,swift,Swift,我想在不改变词源的情况下使词典的值适合阅读。我实现了下面的类来实现它 class DictionaryView<Key, Value> where Key: Hashable { let origin: Dictionary<Key, Value> let map: (Value) -> Value init(_ origin: Dictionary<Key, Value>, map: @escaping (Va

我想在不改变词源的情况下使词典的值适合阅读。我实现了下面的类来实现它

class DictionaryView<Key, Value> where Key: Hashable {
   let origin: Dictionary<Key, Value>
   let map: (Value) -> Value
   
   init(_ origin: Dictionary<Key, Value>,
        map: @escaping (Value) -> Value) {
       self.origin = origin
       self.map = map
    }

   subscript(_ key: Key) -> Value?{
      let value = origin[key]
      return value == nil ? value : map(value!)
   }

}
给我输出:

[“B”:3,“C”:6,“A”:2]
可选(4)
可选(6)

我需要有一个适应,将打印可选(12)而不是零。 怎么做


原始问题:如何在swift中调整词典的值? 我有一本字典
origin

var origin = ["A":2, "B":3]
var origin = ["A":2, "B":3]
并希望创建一个新词典,该词典将基于
源代码
,但包含双值。我天真的解决方案是通过
mapValues

var adapted = origin.mapValues { $0 * 2 }
但是这个解决方案会根据
原点的时刻创建一个新的转换字典。例如,下面的代码

var origin = ["A":2, "B":3]
var adapted = DictionaryView(origin, map: { $0 * 2 })
origin["C"] = 6

print(origin)
print(adapted["A"])
print(adapted["B"])
print(adapted["C"]) 
origin["C"] = 6

print(origin)
print(adapted)
输出

[“A”:1,“B”:2,“C”:6]
[“A”:2,“B”:4]

但我想要真正的适应。我需要一个解决方案,将输出结果如下的代码如上

[“A”:1,“B”:2,“C”:6]
[“A”:2,“B”:4,“C”:12]

我是swift新手,对标准库没有深入的了解。 在开始自行车设计之前,我想问:在swift中,这个问题的通用解决方案是什么


备注1

我在实际情况中发现了这个问题,但创建了一个简化的示例来提取当前问题的本质(避免细节混乱)。但在我看来,要澄清这个问题,真实情况是必要的

我需要实现observable模式,并在obbservable.swift文件中开发了其中的4个部分

订阅:

struct Subscription {
    private let handler: () -> ()
    
    init(cancel handler: @escaping () -> ()) {
        self.handler = handler
    }
    
    func cancel() {
        handler()
    }
}
观察员:

struct Observer<Event> {
    private let handler: (Event) -> ()
    
    init(send handler: @escaping (Event) -> ()) {
        self.handler = handler
    }
    
    func send(_ event: Event) {
        handler(event)
    }
}
struct-Observer{
私有let处理程序:(事件)->()
初始化(发送处理程序:@escaping(Event)->()){
self.handler=handler
}
func send(u事件:事件){
处理程序(事件)
}
}
可观察到:

class Observable<Event> {
    
    fileprivate var observers: [UUID : Observer<Event>] = [:]
    func subscribe(_ observer: Observer<Event>) -> Subscription {
        let id = UUID()
        observers[id] = observer
        return Subscription(cancel: { self.observers[id] = nil })
    }
}
可观察的类{
fileprivate var观察员:[UUID:Observer]=[:]
func subscribe(uo observer:observer)->订阅{
设id=UUID()
观察者[id]=观察者
返回订阅(取消:{self.observators[id]=nil})
}
}
主题:

class Subject<Event> : Observable<Event> {
    private(set) lazy var observer = Observer<Event>(
        send: { event in
            for o in self.observers.values {
                o.send(event)
            }})
}
课程主题:可观察{
私有(集合)惰性var观察者=观察者(
发送:{中的事件
对于o,在self.values{
o、 发送(事件)
}})
}
作为一种常见的方法,我在客户端类外部提供了一个Subject的可观察实例,并在内部作为观察者使用,以实现良好的封装。使用示例:

class Acc {
   private let numberAdded: Observer<Int> 
   let numberDidAdd: Observable<Int>
   
   init() {
     let subject = Subject<Int>()
     numberAdded = subject.observer
     numberDidAdd = subject
   }

   func add(_ number: Int) {
       numberAdded.send(number)
   }
}

let acc = Acc()
acc.numberDidAdd.subscribe(Observer<Int>(send: { print($0) }))
acc.add(4)
acc.add(5)
Acc类{
私人出租编号:观察员
let NumberDiddad:可观察
init(){
让subject=subject()
numberded=主语
numberddad=主题
}
func add(u编号:Int){
编号。发送(编号)
}
}
设acc=acc()
acc.numberddad.subscribe(观察员(发送:{print($0)}))
附件增补(4)
附件增补(5)
当我需要一个简单的事件时,这个解决方案对我很有用。当我需要实现更复杂的事件订阅接口时,问题就出现了。我需要提供一个事件字典(外部观察者,内部观察者)。以下代码是真实上下文的一部分。描述这个上下文并不容易,但我认为可以从代码中捕获它

class RealClass {

    let buttonEvents = ButtonEvents()

    override func viewDidLoad() {
        super.viewDidLoad()

        for (event, observer) in buttonEvents.observers {
            someInternalSubscriptionFunc(event, observer)
        }
        
        buttonEvents.newEventTypeDidAdd.subscribe(
            Observer(send: { event in
                self.someInternalSubscriptionFunc(
                   event, self.buttonEvents.observers[event]!)
            })
    }

    public class ButtonEvents {
        
        private let newEventTypeAdding = Subject<UIControl.Event>()
        private(set) lazy var newEventTypeDidAdd
            : Observable<UIControl.Event> 
            = newEventsTypeAdding
        
        private var subjects: [UIControl.Event : Subject<Point>] = [:]
        fileprivate private(set) lazy var observers
            : [UIControl.Event : Observer<Point>] 
            = subjects.mapValues({ subject in subject.observer })
        
        public subscript(event: UIControl.Event) -> Observable<Point> {
            if subjects[event] == nil {
               subjects[event] = Subject<Point>()
               newEventTypeAdding.send(event)
            }
            
            return subjects[event]!
        }
    }
}

类RealClass{
让buttonEvents=buttonEvents()
重写func viewDidLoad(){
super.viewDidLoad()
用于buttonEvents.observers中的(事件、观察者){
someInternalSubscriptionFunc(事件、观察者)
}
buttonEvents.newEventTypeDidAdd.subscribe(
观察者(发送:{事件在
self.someInternalSubscriptionFunc(
事件,self.buttonEvents.observer[事件]!)
})
}
公共类按钮{
private let newEventTypeAdding=Subject()
private(set)lazy var neweventtypediddad
:可见
=newEventsTypeAdding
私有变量主题:[UIControl.事件:主题]=[:]
fileprivate private(集)惰性var观察员
:[UIControl.事件:观察者]
=subject.mapValues({subject.observer中的subject})
公共下标(事件:UIControl.event)->可观察{
如果受试者[事件]==零{
主题[事件]=主题()
newEventTypeAdding.send(事件)
}
返回主题[事件]!
}
}
}
正如我们所见,按钮事件。观察者是问题的根源


我可以将
observators
重新实现为Computed属性,但在访问字典项时,我将失去O(1)的性能。

正如Martin R所说,如果在生成
调整后修改
原点
数组,则不会影响它。因此,首先创建
原点

var origin = ["A":2, "B":3]
var origin = ["A":2, "B":3]
然后通过添加
origin[“C”]=6来修改它,然后可以创建
adapted
数组

var adapted = origin.mapValues { $0 * 2 }
print(origin)
print(adapted)

这将为您提供您期望的结果。

正如Martin R所说,如果您在生成
调整后修改
原点
数组,将不会影响它。因此,您首先创建
原点

var origin = ["A":2, "B":3]
var origin = ["A":2, "B":3]
然后通过添加
origin[“C”]=6来修改它,然后可以创建
adapted
数组

var adapted = origin.mapValues { $0 * 2 }
print(origin)
print(adapted)

这应该会给你预期的结果。

这是因为

字典是值类型

您应该在这里使用
计算属性

var adapted: [String: Int] {
    return origin.mapValues { $0 * 2 }
}

现在在任何地方调用它,结果将如预期的那样

这是因为

字典是值类型

您应该在这里使用
计算属性

var adapted: [String: Int] {
    return origin.mapValues { $0 * 2 }
}
现在在任何地方调用它,结果将如预期的那样

根据