0

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.

5 Answers 5

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is definitely the right direction IMO, but Input isn't recursive here (and I think it needs to be).
1

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]

Comments

1

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

Comments

0

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/

3 Comments

is there a way to make the ints strings? and then have it all be strings?
Yes, just put them between quotation marks something like this ["+", "5", ["-", "1", ["+", "34", "1"]]]
Now when you retrieve those values they will be strings.. so you won't be able to add/multiply/subtract or divide them unless you transform them into integers again
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.