bobbyyu10
bobbyyu10

Reputation: 25

Creating nested arrays in swift

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

Answers (5)

Feldur
Feldur

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

Price Ringo
Price Ringo

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

Rob Napier
Rob Napier

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

xmhafiz
xmhafiz

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

Pato Salazar
Pato Salazar

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

Related Questions