简体   繁体   中英

Multi-Type and Multi-Dimensional Array (or List or Dictionary)?

Couldnt find exact question... I want to create a list(or dictionary or array, whatever it is called in C#, .NET), where i can store different types of arrays/lists/dicts.

for example, in PHP, i do in this way:

$x= array (
   'Names'=> array( "James", "Nicolas", "Susan"),    //Strings
   'Age'=> array( 18, 52, 37),                       //Int
   'Male'=> array( true, true, false),               //Bool
);

How to achieve similar in C# / .NET ?

ps or if possible, Multi-Multi types, like:

$y = array ( 
    $x => (
     ..... multi-element, like above

    ),
    $z => (
     ..... multi-element, like above

    )
);

Create a class that holds the information as List<string> , List<int> and List<string> . However a much better approach is to hold all the information for a single entity was a single class and store a list of those items:

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool Male { get; set; }
}

Now store instances of that type in a list:

var list = new List<Person> { 
    new Person { Name = "James", Age = 18, Male = true }, 
    new Person { Name = "Nicolas", Age = 52, Male = true }, 
    new Person { Name = "Susan", Age = 37, Male = false }
};

This way you don´t need to "synchronize" all three lists, you have only one list instead.

If you really must use the approach you described define a class holding three different lists:

class Persons
{
    public List<string> Names { get; set; }
    public List<int> Ages { get; set; }
    public List<bool> Male { get; set; }
}

Now you can create your persons as follows:

var persons = new Persons { 
    Names = new List<string> { "James", "Nicolas", "Susan"},
    Ages = new List<int> { 17, 53, 37 },
    Male = new List<bool> { true, true, false }
}

However this is quite difficult as every time you delete a name for example you´d also have to delete the appropriate age- and male-element also. Something like this:

persons.Names.RemoveAt(1);
persons.Ages.RemoveAt(1);
persons.Male.RemoveAt(1);

In pre-version 7, C#, you have to create a class that can store your lists:

class Item {
    public List<string> Names { get; }
    public List<int> Ages { get; }
    public List<bool> Males { get; }
}

You can also use a tuple, with the disadavantage of not having descriptive property names:

Tuple<List<string>, List<int>, List<bool>> tuple =
    Tuple.Create(new List<string>(), new List<int>(), new List<bool>());

In C# 7 you can use value tuples without having to create a class:

(List<string> Names, List<int> Ages, List<bool> Males) itemLists =
    (new List<string>(), new List<int>(), new List<bool>());

And access the components like this:

List<string> names = itemLists.Names;

You should though seriously consider to not create a class that contains lists, but a list that contains classes (or tuples). Here is an example with C# 7 value tuples:

List<(string Name, int Age, bool Male)> list = new List<(string, int, bool)>();

This construct is usually easier to handle, because you can loop one list and then handle one item that contains all related data.

As @HimBromBeere said you may create a Person class:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool Male { get; set; }
}

Now you need to define another class that would store a result

public class Result
{
    public List<string> Names { get; } = new List<string>();
    public List<int> Age { get; } = new List<int>();
    public List<bool> Male { get; } = new List<bool>();
}

At this time you can convert list of persons to your expected output with Linq

var persons = new List<Person> {
      new Person { Name = "James", Age = 18, Male = true },
      new Person { Name = "Nicolas", Age = 52, Male = true },
      new Person { Name = "Susan", Age = 37, Male = false }
  };

var result = persons.Aggregate(new Result(), (c, n) =>
{
    c.Names.Add(n.Name);
    c.Age.Add(n.Age);
    c.Male.Add(n.Male);
    return c;
});

If you are using C# 3 or higher you can use anonymous objects:

var x = new
{
    Names = new[] {"James", "Nicolas", "Susan"},
    Age = new[] {18, 52, 37},
    Male = new[] {true, true, false}
};

for your second example you may use this code:

var y = new
{
    x = new
    {
        Names = new[] {"James", "Nicolas", "Susan"},
        Age = new[] {18, 52, 37},
        Male = new[] {true, true, false}
    },
    // z = new { /* same code as above */ }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM