Computed property with a subscripted struct

64 Views Asked by At

I have a struct ExampleStruct with a custom subscript. The struct data are a fixed private dictionary, value. The structure has one element Sum that is essentially a summation of the the other elements in private dictionary

struct ExampleStruct {
   private var value: [String:Double] {
     didSet {
     value["Sum"] = value.filter{$0.key != "Sum"}.reduce(0.+)
     }
   }

   init(){
      value = ["Ind1":12, "Ind2":13, "Sum":25]
   }
   subscript(index: String) -> Double {
     get {
// some error checking too about index
       return value[index]
     }
     set {
       value[index] = newValue
     }

I want to use this struct as a computed property that depends on another function which depends on the value of the struct with the "Sum" index through another dependent function. sampleFunc is something like:

func sampleFunc() -> ExampleStruct {
...
     sampleFunc2(sum: exampleImplementation["Sum"])
...
}

I was using the following but it was recursive:

var exampleImplementation: ExampleStruct {  
     return sampleFunc()   //sampleFunc depends on exampleImplementation["Sum"]
                     //func returns ExampleStruct   
   }
}

But I only need the function to set the indices other than "Sum". So I want something like:

var exampleImplementation: ExampleStruct {  
   if INDEX=="SUM" {   //
      return SOME BACKING VALUE 
   } else {
     return sampleFunc()[INDEX NOT EQUAL TO "Sum"]   //func depends on exampleImplementation["Sum"]
                     //func returns ExampleStruct   
   }
}

Is there a way to achieve this for a struct that has a subscript in a computed property?

1

There are 1 best solutions below

0
Joakim Danielson On

If we ignore the inconsistent code isn't the solution simply to add a filter to the set part of the subscript method?

set {
    if index == "Sum" { return }
    value[index] = newValue
}

My edition of the complete struct

struct ExampleStruct {
    static let Sum = "Sum"
    private var value: [String:Double] {
        didSet {
            value[Self.Sum] = value.filter{$0.key != Self.Sum}.map(\.value).reduce(0 , +)
        }
    }

    init(){
        value = ["Ind1":12, "Ind2":13, "Sum":25]
    }
    subscript(index: String) -> Double? {
        get {
            value[index]
        }
        set {
            if index == Self.Sum { return }
            value[index] = newValue
        }
    }

    var sum: Double {
        value[Self.Sum, default: 0]
    }
}

An example

var example = ExampleStruct()

example["Ind1"] = 3
example["Ind2"] = 3
example["Ind3"] = 3
example[ExampleStruct.Sum] = 3
print(example.sum)

9.0