Dictionary-like access to Array

I made an extension for an array:

public extension Array where Element:SpaceCoordinateProtocol {
	subscript <A:SpaceAxisProtocol>(_ axis:A) -> Element? where A == Element.Axis
	{
		get {
			return self.first(where: {$0.axis == axis})
		}
		set {
			if let coordinate = newValue,
				let index = self.firstIndex(where: {$0.axis == coordinate.axis })
			{
				self[index].at = coordinate.at
			}
		}
	}
}

When I get value, it works OK,

var l = axes[bold].at

But if I try to set value:

axes[bold].at = 3.6

I have compiler error Cannot convert value of type 'Axis' to expected argument type 'Int'

Is this behaviour expected? Is it possible to use axis[bold].at = something?

Assuming that

  • bold isn't an Int, and that it implements SpaceAxisProtocol
  • at is a property on SpaceCoordinateProtocol
  • You didn't add at property on Optional

then var l = axes[bold].at shouldn't work even though you say it works. axes[bold] is an Optional<Element>, which doesn't have a at property. Did you forget to write a question mark? Is any of my assumptions wrong?

OK, but this works.

// `at` is defined
if var coordinate = coordinates[axis] {  // No error
	coordinates[axis].at = at // error
}

OK, I got it

 coordinates[axis]!.at = at

There are two minor things:

  1. Since the type constraint is ==, most likely you can just substitute them,
public extension Array where Element: SpaceCoordinateProtocol {
    subscript(_ axis: Element.Axis) -> Element? { ... }
}
  1. Swift tends not to include Protocol in protocol names, and instead use noun phrases or has -able suffixes. An exception is when there's a collision with a closely related class/struct/associatedtype.

Thank you! Sometimes I feel lost in protocols, where etc. It's clear now.