1

I would like to know if C# has a way of defining strongly-typed nested jagged arrays without using object[].

Something like:

var nested = new {1, 2, {3, {4, 5}, 6}, 7};

I would like to have a nested array of int.

Consider this array below: [[1, 2, [3]], 4, [5], [[[6]]]]

This is how I've done it:

var myNestedJagged = new object[]
{
    new object[]
    {
        1, 2, new object[] {3}
    },
    4,
    new object[] {5},
    new object[] {new object[] {new object[] {6}}}
};
Igor
  • 60,821
  • 10
  • 100
  • 175
Leandro Andrade
  • 115
  • 1
  • 10
  • 1
    The only way I think you could start to strongly type this Jagged Array is by creating classes and using generics withinin those classes to represent your Jagged Array – Brian Ogden Sep 12 '18 at 20:53
  • Yeah, I thought so. I would like to know if there's a way of doing it using something like `new int[][] { }` – Leandro Andrade Sep 12 '18 at 20:55
  • This is so ridiculously easy with javascript, but C# seems to have its limitations with such dynamic array – Leandro Andrade Sep 12 '18 at 20:56
  • 3
    No I do not think you could express a jagged array like that C#, pros and cons to every programming language – Brian Ogden Sep 12 '18 at 20:57
  • 6
    Hate to nitpick, but this is not a jagged array. A jagged array is an array that contains arrays of different lengths, such as `{ { 1 }, { 1, 2, 3, 4}, { 1, 2 }, { 1, 2, 3, 4, 5, 6, 7 } }`. – Michael Gunter Sep 12 '18 at 20:59
  • You are right @MichaelGunter. That's why I tried naming it a nested-jagged. – Leandro Andrade Sep 12 '18 at 21:03
  • I think you just want a node list (tree structure). There is nothing language native that would support this though, you have to create your own type(s). – Igor Sep 12 '18 at 21:06
  • @Leandro but javascript is not strongly typed :-) – stephanV Sep 12 '18 at 21:11

2 Answers2

4

The only way I can think to improve it something like this. This is strongly-typed, and it allows you to have separate logic depending upon type of node (by either doing explicit is checks to determine which type of node, or by doing some sort of OO technique where an operation is described as an abstract method in the base Node and implemented separately in Tree and Leaf according to how each should behave, or by implementing a Visitor pattern).

// all items are nodes
abstract class Node
{
}

// a tree is just a collection of nodes; it has no value
class Tree : Node
{
    public Tree(params Node[] children)
    {
        Children = children;
    }
    public IReadOnlyCollection<Node> Children { get; }
}

// a leaf is just a value; it has no children
class Leaf : Node
{
    public Leaf(int value)
    {
        Value = value;
    }
    public int Value { get; }
}

However, the construction is kinda ugly.

var myTree = new Tree(
    new Tree(
        new Leaf(1),
        new Leaf(2),
        new Tree(
            new Leaf(3)
        )
    ),
    new Leaf(4),
    new Tree(
        new Leaf(5)
    ),
    new Tree(
        new Tree(
            new Leaf(6)
        )
    )
);
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58
0

Depending on your use, you could use tuples:

var a = (1, 2, (3, (4, 5), 6), 7);
var b = ((1, 2, (3)), 4, (5), (((6))));

The limitation is that after you create them you can't (easily) resize them.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Pretty sure you can't create a 1-tuple using tuple-syntax as `(x)` already has a meaning which it had prior to the introduction of tuple syntax (it resolves to simply, `x`) – pinkfloydx33 Sep 12 '18 at 23:40