Reputation: 25
I'm trying to create nested arrays in Swift of data that's input in the following format:
(+ 5 (- 1 (+ 34 1)))
So the nested array would look like:
[+, 5, [-, 1, [+, 34, 1]]]
with arr[0] always being the operation (+,-,*, or /)
I'm very new to swift and don't really know where to start, so I'd really appreciate the help.
Upvotes: 0
Views: 1044
Reputation: 1169
Your example looks like a classic Lisp expression. Reflecting that, have you considered the possibility that arrays are a force fit, and you might have an easier time of it with lists as the underlying representation? A list data type would be trivial to implement.
Upvotes: 0
Reputation: 3440
You can put integers, strings, and even functions in the same array by using an enumeration and its associated values. The example does not lend itself to an array but simply a recursive nesting of numbers and computations.
enum Input {
case Operator((Int, Int) -> Int)
case Number(Int)
}
Edit: Per Rob's suggestion.
enum Input {
case Operator((Int, Int) -> Int)
case Number(Int)
indirect case Computation(operator: Input, left: Input, right: Input)
}
This shows how to declare a recursive enumeration. I wish there was a way to limit the operator parameter to Input.Operator
and parameters left
and right
to Input
types not .Operator
.
Upvotes: 4
Reputation: 299703
As Price Ringo suggests, a recursive enum
is definitely the right tool here. I would build it along these lines:
enum Operator {
case Add
case Subtract
}
enum Expression {
indirect case Operation(Operator, Expression, Expression)
case Value(Int)
}
let expression = Expression.Operation(.Add,
.Value(5),
.Operation(.Subtract,
.Value(1),
.Operation(.Add, .Value(34), .Value(1))))
If you wanted to, you could do it Price's way with functions, and that's probably pretty clever, but I suspect would actually be more of a headache to parse. But if you wanted to, it'd look like this:
enum Expression {
indirect case Operation((Int, Int) -> Int, Expression, Expression)
case Value(Int)
}
let expression = Expression.Operation(+,
.Value(5),
.Operation(-,
.Value(1),
.Operation(+, .Value(34), .Value(1))))
Alternately, you could create an Operator
type rather than passing in functions. That's how I'd probably recommend going unless you really want to be able tow
Upvotes: 1
Reputation: 3538
you could use array with type of AnyObject as below example.
let arr: [AnyObject] = ["+", 5, ["-", 1, ["/", 34, 1]]]
So in order to get operand you can get at index 0. Let say you want operand division "/" as sample above you can go at this index
arr[2][2][0]
Upvotes: 1
Reputation: 1477
I think you can't build the arrays with different types.. I mean you want to build an Array with Integers and the operators should be Strings... but you can't have both in an array.
check this link, it might be helpful http://totallyswift.com/nested-collections/
Upvotes: 0