Repository: vapor/vapor
File: Sources/Vapor/FormURLEncoded/StructuredData+FormURLEncoded.swift (Swift)

Code before:
                    var array = existing.array ?? [existing]
                    array.append(value)
                    value = .array(array)
                }
            } else if keyIndicatedArray {
                value = .array([value])
            } else if keyIndicatedObject {
                value = .object([subKey: value])
            }

            urlEncoded[key] = value

        }
        
        self = .object(urlEncoded)
    }
    
    public func formURLEncoded() throws -> Bytes {
        guard let dict = self.object else { return [] }

        var bytes: [[Byte]] = []

        for (key, val) in dict {
            var subbytes: [Byte] = []

            if let object = val.object {
                subbytes += object.formURLEncoded(forKey: key).makeBytes()
            } else {
                subbytes += key.urlQueryPercentEncoded.makeBytes()
                subbytes.append(.equals)
                subbytes += val.string.formURLEncodedValue().makeBytes()
            }

            bytes.append(subbytes)
        }

        return bytes.joined(separator: [Byte.ampersand]).array
    }
}

extension Dictionary where Key == String, Value == Node {
    fileprivate func formURLEncoded(forKey key: String) -> String {
        let key = key.urlQueryPercentEncoded
        let values = map { subKey, value in
            var encoded = ""
            encoded += key
            encoded += "[\(subKey.urlQueryPercentEncoded)]="
            encoded += value.string.formURLEncodedValue()
            return encoded
        } as [String]


Review comment (suggestion):
we should also support arrays while we are here. 

i believe you can do arrays just like you can in html but i'm not 100% sure

```
foo[]=1&foo[]=2 // foo = [1,2]
```

Code after:
                    var array = existing.array ?? [existing]
                    array.append(value)
                    value = .array(array)
                }
            } else if keyIndicatedArray {
                value = .array([value])
            } else if keyIndicatedObject {
                value = .object([subKey: value])
            }

            urlEncoded[key] = value

        }
        
        self = .object(urlEncoded)
    }
    
    public func formURLEncoded() throws -> Bytes {
        guard let dict = self.object else { return [] }

        var bytes: [[Byte]] = []

        for (key, val) in dict {
            var subbytes: [Byte] = []

            if let object = val.object {
                subbytes += object.formURLEncoded(forKey: key).makeBytes()
            } else if let array = val.array {
                subbytes += array.formURLEncoded(forKey: key).makeBytes()
            } else {
                subbytes += key.urlQueryPercentEncoded.makeBytes()
                subbytes.append(.equals)
                subbytes += val.string.formURLEncodedValue().makeBytes()
            }

            bytes.append(subbytes)
        }

        return bytes.joined(separator: [Byte.ampersand]).array
    }
}

extension Array where Element == Node {
    fileprivate func formURLEncoded(forKey key: String) -> String {
        let key = key.urlQueryPercentEncoded
        let collection = map { val in
            "\(key)[]=" + val.string.formURLEncodedValue()
        }
        return collection.joined(separator: "&")
    }
}