1

I have extended the Array class in order to create some methods. However I am not being able to append to the array:

private extension Array
{
    mutating func addCharacterWithIndex(char: String, index: Int)
    {
        let dict = [
            "char": char,
            "index": index
        ]
        self.append(dict) //Shows error: Cannot invoke 'append' with argument list of type '(NSDictionary)'
    }
}

The only way I could make this go away was by using

self.append(dict as! Element)

However the element is not being added to the array at all.

What am I not understanding about this situation? Is this even possible?

ZeMoon
  • 20,054
  • 5
  • 57
  • 98
  • 1
    you are extending any type of array so if you try to append a dictionary to an array of integers it will crash – Leo Dabus Mar 10 '16 at 16:57
  • @LeoDabus how do I specify the type of array? – ZeMoon Mar 10 '16 at 16:57
  • @ZeMoon Can you give us an example usage of this method? Like what's the input, what's the expected output so we can understand more about your need. – J.Wang Mar 10 '16 at 23:43
  • @J.Wang I'd like to mark the positions of various special characters while parsing a string. So i will be calling the code like `symbols.addCharacterWithIndex("*", index: 9)` – ZeMoon Mar 11 '16 at 03:43
  • @ZeMoon Okay, so you want to have an array of dictionary? I see. – J.Wang Mar 11 '16 at 03:46

1 Answers1

1

Updated

I just realized DictionaryLiteralConvertible can be used here.

extension Array where Element: DictionaryLiteralConvertible, Element.Key == String, Element.Value == Int {
    mutating func addCharacterWithIndex(char: String, index: Int)
    {
        self.append(Element.init(dictionaryLiteral: (char, index)))
    }
}

Original answer...


Since Array in Swift is a generic struct, it's not possible (at least right now) to extend the Array with a specific type constraint.

For you question, one way to do is to make it optional.

extension Array
{
    mutating func addCharacterWithIndex(char: String, index: Int)
    {
        if let dict = [
            "char": char,
            "index": index
            ] as? Element {
            self.append(dict)
        }
    }
}

So you can use it like this:

var symbols: [[String: AnyObject]] = []
symbols.addCharacterWithIndex("*", index: 9)

However, this is not consistent. For other arrays such as [Int], [String] this method is accessible but does nothing.

Another way, given that you're only using append method, you can extend RangeReplaceableCollectionType instead.

extension RangeReplaceableCollectionType where Generator.Element == NSDictionary {
    mutating func addCharacterWithIndex(char: String, index: Int)
    {
        let dict = [
            "char": char,
            "index": index
        ]

        self.append(dict)
    }
}

And use it like this:

var symbols: [NSDictionary] = []
symbols.addCharacterWithIndex("*", index: 9)
J.Wang
  • 1,136
  • 6
  • 12