using array of array of list of lists? C# - arrays

Im not an IT guy and trying some programming in his spare time and was wondering how to tackle following issue. It must be very very simple but can`t figure it out, even after dozen of read articles on stackoverflow.
I have a series of values which I need to put in a list or array which goes in another array or list. Like this:
Series one:
"name","Madman"
"dateOfBirth", 11/03/1990 //which is a DateTime object.
"hobby","chopping up family members"
Series two
"name","Dad"
"dateOfBirth", 11/03/1965 //which is a DateTime object.
"hobby","biking"
Series one and two go in another list like this:
allSeries: Series one, Series two
Any ideas? Thanks very much!

Create a class (possibly named Person) that has attributes name, dateOfBirth, and hobby (this encapsulates the data). Set the data through a constructor or setter methods. Then store the instances of Person into a list, or array, or whatever you choose - probably called people. Example: List<Person> people = new List<Person>();.
In your original approach you would have had to have declared your storage data structure as a more generic type. A nice bonus of this approach is that you know the types of the data stored in the class.

so depending on the language you are using you would make another list/array and make an array of arrays (or array of lists). Which language are you using? in Java you would make a List<List<String>> object for example and add things like this. Hope this is a start.
Edit: for c# see: http://www.dotnetperls.com/nested-list

I would do this: create a class containing your attributes, then place multiple instances in a list.
public class Person
{
public string name {get;set;}
public Date dateOfBirth {get; set;}
public string hobby {get;set;}
}
And place them in a list like so: {person1; person2,...}

Related

Is there a technical reason why I cannot declare a public array in a VBA class?

I just discovered that it's apparently not possible to declare a public array in a VBA class while it is fine to declare it private.
I am wondering if this is has a technical reason or if this is a design choice on Microsoft's part.
Either explanation doesn't make much sense to me: I cannot see a technical reason that would prevent a member to be private while it can be public as this is only an access check that is checked at runtime.
On the other hand, I don't understand why it shouldn't be possible to declare public arrays while it is perfectly fine to declare public integers or other data types.
I'd appreciate if someone could explain the rational behind all this.
I believe you'd need to ask the persons who created the Visual Basic (or maybe even Basic) programming language as to "why". It seems to be inherent to the languages. As far as VBA goes, the restriction comes from VB6, on which VBA bases. I find this reference in a Google search:
Declaring data as Public in a Form means you are creating a Property
on that Form, using abbreviated syntax. A Property cannot be an array
using that shortcut syntax.
To say this another way, "Public" only means "global" for
old-fashioned static (BAS) modules. For everything else Public means
something entirely different.
And this:
Instead of Arrays, You can use Collection object or Your own
Collection Class. VB6 does not allow to declare Constants, Arrays,
User Defined Types as Public.
From the VBA Help topic Constants, fixed-length strings, arrays, user-defined types, and Declare statements not allowed as Public members of an object module
Not all variables in an object module can be declared as Public.
However, procedures are Public by default, and Property procedures can
be used to simulate variables syntactically. This error has the
following causes and solutions:
Concerning arrays, specifically
You declared a Public array in an object module. Although a procedure
can't return an array, it can return a Variant that contains an array.
To simulate a Public array in a class module, use a set of Property
procedures that accept and return a Variant containing an array.

How to create an array of actions?

I am writing a VB.NET Class, and I have run into the issue of needing to create an array of actions. How does one do that in VB.NET?
UPDATE: I am trying to write a collision detection class that stores objects to collide with, and functions to execute when the collision happens with indexes that line up the object to the function.
So like:
Class CDE
Private Collidables As Windows.Forms.Control()
Private Actions As 'Action Array
There's not enough info to provide a specific answer here, but you would create this array the same as you would create any other array in VB.NET.
Dim actionsArr = New MyAction() {action1, action2, action3, action4}
On a side note, I've always been more fond of using Lists over arrays. It's much easier to add and modify items in a list.
https://msdn.microsoft.com/en-us/library/bb385204.aspx

In VB 2008, how can one subprocedure accept different arrays of a structure in different calls?

I'm writing a character creator for my friend's tabletop RPG using Visual Basic 2008 as a learning exercise so please be kind if I've made stupid choices. :]
I have three arrays of a structure, one called m_OwnedWeapons that's created from a structure called Weapons, one called m_OwnedArmor created from a structure called Armor, and one called m_OwnedPotions created from a structure called Potions. They have some similarities and several differences but a lot of the time I need to do an identical operation on each of them. For example, when the index in a listbox changes, my program searches through each of these arrays of a structure to find which holds the item and then it updates the displayed values (cost, description, etc).
My problem is that I'd like a way that I only have to write the search code one time. Right now I have to write it three times because it has to search each by name. I have this same code posted three times, only once it refers to m_OwnedPotions, once it refers to m_OwnedArmor, and once it refers to m_Owned Weapons:
LoopCountInteger = 0
If m_OwnedPotionsCounterInteger > 0 Then
Do Until LoopCountInteger >= m_OwnedPotionsCounterInteger Or ItemFoundBoolean = True
If InventoryListBox.SelectedItem.Equals(m_OwnedPotions(LoopCountInteger).NameString) Then
ItemFoundBoolean = True
End If
LoopCountInteger += 1
Loop
End If
Is there a way to maybe write some kind of subprocedure with this code that accepts the array of a structure name as its parameter? Is this not possible because one is an array of a structure of Weapons, one of Armor, and one of Items?
Maybe I just need one array of a structure called Items that will hold the fields required by all item types, but if I do it that way it seemed untidy because that one structure had so many fields unused for most items. I don't know.
Thanks for any help and suggestions.
So solving this type of problem is normally done through inheritance. You have three different types of objects that share some basic properties but are also different things. To represent these objects in your code, create a base class that will hold their common properties (name, cost, description, etc.) and a subclass for each of the more concrete types.
Here is one sort of exammple:
Public Class Equipment
Public Name As String
Public Desc As String
Public Cost As Integer
Public Weight As Integer
End Class
Public Class Weapon
Inherits Equipment
Public MinimumDamage As Integer
Public MaximumDamage As Integer
Public Speed As Integer
End Class
Public Class Potion
Inherits Equipment
Public Effect As String
End Class
Public Class Armor
Inherits Equipment
Public SpeedPenalty As Integer
Public ArmorClass As Integer
End Class
Now, using polymorphism you can write procedures that can operate on any of these items by accepting a parameter of the base type. Your program can also have a container that holds all of the equipment so you only have to search one list to find the object that is selected.

Immutable data model for an WPF application with MVVM implementation

I have an application which has a data tree as a databackend. To implement the the MVVM pattern I have a logic layer of classes which encapsulate the data tree. Therefore the logic also is arranged in a tree. If the input is in a valid state the data should be copied to a second thread which works as a double buffer of the last valid state. Therefore one way would be cloning.
Another approach would be to implement the complete data backend to be immutable. This would imply to rebuild the whole data tree if something new is entered. My question is, is there a practical way to do this? I'm stuck at the point where I have to reassign the data tree efficently to the logic layer.
**UPDATE - Some Code
What we are doing is to abstract hardware devices which we use to run our experiments. Therefore we defined classes like "chassis, sequence, card, channel, step". Those build a tree structure like this:
Chassis
/ \
Sequence1 Sequence2
/ | \
Card1 Card2 Card3
/ \
Channel1 Channel2
/ \
Step1 Step2
In code it looks like this:
public class Chassis{
readonly var List<Sequence> Sequences = new List<Sequence>();
}
public class Sequence{
readonly var List<Card> Cards = new List<Card>();
}
and so on. Of course each class has some more properties but those are easy to handle. My Problem now is that List is a mutable object. I can call List.Add() and it changed. Ok there is a ReadOnlyList but I'm not sure if it implements the immutability the right way. Right as in copy by value not reference and not just blocking to write to it by blocking the set methods.
The next problem is that the amount of sequences and step can vary. For this reason I need an atomic exchange of list elements.
At the moment I don't have any more code as I'm still thinking if this way would help me and if it is possible at all to implement it in a reasonable amount of time.
Note that there are new immutable collections for .NET that could help you achieve your goal.
Be very cautious about Dave Turvey's statement (I would downvote/comment if I could):
If you are looking to implement an immutable list you could try storing the list as a private member but exposing a public IEnumerable<>
This is incorrect. The private member could still be changed by its container class. The public member could be cast to List<T>, IList<T>, or ICollection<T> without throwing an exception. Thus anything that depends on the immutability of the public IEnumerable<T> could break.
I'm not sure if I understand 100% what you're asking. It sounds like you have a tree of objects in a particular state and you want to perform some processing on a copy of that without modifying the original object state. You should look into cloning via a "Deep Copy". This question should get you started.
If you are looking to implement an immutable list you could try storing the list as a private member but exposing a public IEnumerable<>
public class Chassis
{
List<Sequence> _sequences = new List<Sequence>();
public IEnumerable<Sequence> Sequences { get { return _sequences; } }
}
18/04/13 Update in response to Brandon Bonds comments
The library linked in Brandon Bonds answer is certainly interesting and offers advantages over IEnumerable<>. In many cases it is probably a better solution. However, there are a couple of caveats that you should be aware of if you use this library.
As of 18/04/2013 This is a beta library. It is obviously still in development and may not be ready for production use. For example, The code sample for list creation in the linked article doesn't work in the current nuget package.
This is a .net 4.5 library. so it will not be suitable for programs targeting an older framework.
It does not guarantee immutability of objects contained in the collections only of the collection itself. It is possible to modify objects in an immutable list You will still need to consider a deep copy for copying collections.
This is addressed in the FAQ at the end of the article
Q: Can I only store immutable data in these immutable collections?
A: You can store all types of data in these collections. The only immutable aspect is the collections themselves, not the items they contain.
In addition the following code sample illustrates this point (using version 1.0.8-beta)
class Data
{
public int Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var test = ImmutableList.Create<Data>();
test = test.Add(new Data { Value = 1 });
Console.WriteLine(test[0].Value);
test[0].Value = 2;
Console.WriteLine(test[0].Value);
Console.ReadKey();
}
}
This code will allow modification of the Data object and output
1
2
Here are a couple of articles for further reading on this topic
Read only, frozen, and immutable collections
Immutability in C# Part One: Kinds of Immutability

How to assignTo a setter in Salesforce that requires an index parameter, such as a List<>?

In a controller I have two values:
public List<String> StringValue {get; set;}
public List<String> ListValue {get; set;}
The ListValue is initialized in the constructor and several strings are added. At this point in a value I can refer to these with {!StringValue} and {!ListValue[1]} in a VisualForce page. The list one in particular is the focus - I can even add pseudo-constants (getters) as indexes, making {!ListValue[nameIndex]} a valid reference.
However I've run into an exception when trying to set a list value instead of a simple string value.
<apex:param value="123" assignTo="{!ListValue[1]}" />
The exception is java.lang.ClassCastException: java.lang.String cannot be cast to common.formula.FormulaFieldReference
I think I understand the basics of the problem - Salesforce can't create a setter reference that includes an index parameter (meaning only setters that take a single parameter can be referenced).
Is there any way around this, or do I just have to create a massive amount of ListValue1, ListValue2 variables and associated code?
It's a hack, but it avoids you having to create dozens of variables.
<apex:param value="1:123" assignTo="{!smartAssigner}" />
Then in your controller:
public void setSmartAssigner(String myval) { // parse the colon, set list value appropriately.
You get the idea.
I've never come across a way to do this in the style you're requesting, I'd suggest that to get this going the easiest thing to do would be to concatenate the values you want into one parameter and then split them back up inside the controller.
You might find a suitable way to do this with <apex:repeat> but I'm not sure on your full use case.

Resources