Create List with name from variable - c#

Is it possible in C# to create a list and name it from a variable or similar?
Let's say I have a list with 10 rows in it:
a, b, c, d, e, f, g, h, i, j
Can I make 10 lists from this list, each having a name like one of the rows?
Something like
List<string> myList = new List<string>();
foreach (var line in myList)
{
List<string> line = new List<string>();
}
What I want is to make a few lists to store data in, but I won't know the names before the program runs so it needs to generate those dynamically.

Sounds like you want a Dictionary of List<string>s:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
foreach (var line in myList)
{
dict.Add(line, new List<string>());
}
Now you can access each list based on the original string we used for the key:
List<string> aList = dict["a"];

You could try something like this:
var newList = new Dictionary<string, List<string>>();
foreach (var line in myList)
{
newList.Add(line, new List<string>());
}
This will give you the data structures in which to store your new data and will allow you to reference them based on the names in the first list.

It seems that you want a Dictionary<String, List<String>> like this:
var data = myList
.ToDictionary(line => line, line => new List<string>());
And so you can
check if "variable" exists
if (data.ContainsKey("z")) {...}
address "variable"
data["a"].Add("some value");
add "variable"
data.Add("z", new List<string>());

Related

Compare 2 dictionaries and return missing values

How would I compare these 2 dictionaries and return only the values missing?
The GetFileListFromBlob() function gets all file names and I'd like to know what is missing from the db.
Or is there a better way to get the missing values from these objects? Should I use different key/ value?
Dictionary<int, string> databaseFileList = new Dictionary<int, string>;
Dictionary<int, string> blobFileList = new Dictionary<int, string>;
int counter = 0;
foreach (string f in GetFileListFromDB())
{
counter++;
databaseFileList.Add(counter, f );
}
counter = 0;
foreach (string f in GetFileListFromBlob())
{
counter++;
blobFileList.Add(counter, f);
}
// How to compare?
Thank you
A HashSet<T> might be what you want (instead of a Dictionary<K,V>) - take this example:
var reference = new HashSet<string> {"a", "b", "c", "d"};
var comparison = new HashSet<string> {"a", "d", "e"};
When you now call ExceptWith on the reference set ...
reference.ExceptWith(comparison);
... the reference set will contain the elements "b" and "c" that do not exist in the comparison set. Note however that the extra element "e" is not captured (swap the sets to get "e" as the missing element) and that the operation modifies the reference set in-place. If that isn't wished for, the Except LINQ operator might be worth investigating, as was already mentioned in another answer.
The way I see it, you don't need counters at first (you can add them later).
You can use System.Collections.Generic.List<> type to go on.
List<int, string> databaseFileList = new List<string>(GetFileListFromDB());
List<int, string> blobFileList = new List<string>(GetFileListFromBlob());
//some code
Now if you want to get all items in both lists you can simply use Concat(...) method to unify them and then use Distinct() method to remove duplicate items:
List<string> allItems = databaseFileList.Concat(blobFileList).Distinct();
Now use Except(...) method to compare collections:
var missingItems1 = allItems .Except(databaseFileList);
//or
var missingItems1 = allItems .Except(blobFileList);
//or
//some other code
private void CompareDictionary()
{
var databaseFileList = new Dictionary<int, string>();
var blobFileList = new Dictionary<int, string>();
databaseFileList.Add(300, "apple");
databaseFileList.Add(500, "windows");
databaseFileList.Add(100, "Bill");
blobFileList.Add(100, "Bill");
blobFileList.Add(200, "Steve");
var result = databaseFileList.Where(d2 => !blobFileList.Any(d1 => d1.Key == d2.Key)).ToList();
}

Best way to hold sets of related elements dynamically added

I have a list of files, and the filenames for those files contain some characters then an underscore, then anything else like so:
test_123.txt
What I'm trying to do is loop through these files, pull out the 'prefix' (the characters up to but not including the _, add the prefix to a list if it's not already in the list, and then add the whole filename as an element of that prefix.
That might be confusing so here's an example:
List of file names:
A_ieie.txt
B_ldld.txt
C_test.txt
A_232.txt
B_file2.txt
C_345.txt
So I am looping through these files and get the prefix like so:
string prefix = fileName.Substring(0, fileName.IndexOf('_'));
Now, I check if that prefix is already in a list of prefixes, and if not, add it:
List<string> prefixes = new List<string>();
if (!prefixes.Contains(prefix))
{
prefixes.Add(prefix);
}
So here's the prefixes that would be added to that list:
A //not yet seen, add it to list
B //not yet seen, add it to list
C //not yet seen, add it to list
A //already seen, don't add
B //already seen, don't add
C //already seen, don't add
Okay the above is easy to do, but what about when I want to add the filenames that share a prefix to a list?
Since these are going to be dynamically added and could be anything, I can't make several lists before hand. I thought about have a List of lists, but is that really the best way to do this? Would a class be ideal?
The end goal of the above example would be something like :
[0][0] = A_ieie.txt //This is the 'A' list
[0][1] = A_232.txt
[1][0] = B_ldld.txt //This is the 'B' list
[1][1] = B_file2.txt
[2][0] = C_test.txt //This is the 'C' list
[2][1] = C_345.txt
Sounds like you want a Dictionary:
var list = new Dictionary<string, List<string>>();
The Key would be the "prefix" and the Value would be a list of strings (the filenames).
EDIT
If you want the list of filenames to be unique, perhaps a HashSet is a better option:
var list = new Dictionary<string, HashSet<string>>();
Sounds like you want a Dictionary>
Then, each list is referenced by a key integer (or use a string to "name" the list):
public Dictionary<string, List<string>> myBookList = new Dictionary<string, List<string>>();
private void addList(string listName, List<string> contents)
{
myBookList.Add(listName, contents);
//direct add
List<string> science_Fiction_Books = new List<string>();
myBookList.Add("Science Fiction", science_Fiction_Books);
myBookList["Science_Fiction"].Add("mytitle.txt");
myBookList["Science_Fiction"][0] = "My book title.txt";
string fileLocation = #"c:\mydirectory\mylists\myBookTitle.txt";
myBookList["Science_Fiction"].Add(System.IO.Path.GetFileName(fileLocation));
//etc.
}
You can use linq to achieve this.
List<string> List = new List<string>() { "A_ieie.txt", "B_ldld.txt", "C_test.txt", "A_232.txt", "B_file2.txt", "C_345.txt" };
Dictionary<string, List<string>> Dict = new Dictionary<string, List<string>>();
Dict = List.GroupBy(x => x.Split('_')[0]).ToDictionary(x => x.Key, x => x.ToList());
How about this:
var textFileNameList =
new List<string>{"A_ieie.txt","B_ldld.txt","C_test.txt",
"A_232.txt","B_file2.txt","C_345.txt"};
var groupedList = textFileNameList.GroupBy(t => t.Split('_')[0])
.Select( t=> new {
Prefix = t.Key,
Files = t.Select( file=> file).ToList()
}).ToList();

single key but multiple value different row

I have
Dictionary idDictionary = new Dictionary();
within this Dictionary, I want, add two row with same key but values different
I used this Dictionary in many methods that a global Dictionary in one method has that issue. if I changed like all u suggest another method get error
Try something like this.
Dictionary<string, List<string>> obj = new Dictionary<string, List<string>>();
List<string> keyValue = new List<string>();
keyValue.Add("a");
keyValue.Add("b");
obj.Add("key1", keyValue);
foreach (KeyValuePair<string, List<string>> entry in obj)
{
// do something with entry.Value or entry.Key
}
List<string> keyValueOutput = new List<string>();
if (obj.TryGetValue("key1",out keyValueOutput))
{
foreach (string s in keyValueOutput)
{
// do something with entry.Value or entry.Key
}
}

Adding new element within a list inside a dictionary

In a dictionary, I want to add a list of numbers for a given key.But I am unable to do it.
for(int i = 0 ; i < size ; i++){
string input = Console.ReadLine();
string[] inputList = input.Split(' ');
count[Convert.ToInt32(inputList[0])]++;
if(!map.ContainsKey(Convert.ToInt32(inputList[0]))){
map.Add(Convert.ToInt32(inputList[0]),new List<string>());
map_index.Add(Convert.ToInt32(inputList[0]),new List<int>());
}
}
The question is bit unclear. My understanding of your problem is as follows: You have a dictionary, a value of the dictionary is a list, and you have trouble adding an item to that list. Since you didn't explain your notation I'm using more general names, just to give you an idea what has to be done:
Dictionary<int, List<string>> myDict = new Dictionary<int, List<string>>();
if (myDict.ContainsKey(myKey))
{
myDict[myKey].Add(myVal);
}
else
{
myDict[myKey] = new List<string> { myVal };
}
If the key is not in the dictionary you create an entry together with the list and initialize the list with the new value. If the key is there you just access the list (by using myDict[myKey]) and add the new value to the list. Since the list is always created for a new key you don't have to worry that it's not initialized when adding a value for an existing key.
This could be one the efficient Solution and much easier than if-else.
Dictionary<int, List<string>> myDict = new Dictionary<int, List<string>>();
try
{
myDict[myKey].Add(myVal);
}
catch
{
myDict[myKey] = new List<string> { myVal };
}
There is a 'one-command-line' way to do this using AddOrUpdate from ConcurrentDictionary:
using System.Linq;
using System.Collections.Generic;
using System.Collections.Concurrent;
...
var dictionary = new ConcurrentDictionary<int, string[]>();
var itemToAdd = "item to add to key-list";
dictionary.AddOrUpdate(1, new[]{item1ToAdd}, (key, list) => list.Append(itemToAdd));
// If key 1 doesn't exist, creates it with a list containing itemToAdd as value
// If key 1 exists, adds item to already existent list (third parameter)

.NET List<string> (call by reference?) with Dictionary objects

I have the following code snippet:
Dictionary<int, List<string>> likeListDict = new Dictionary<int, List<string>>();
List<string> lists = new List<string>();
lists.Add("hello");
lists.Add("world");
likeListDict.Add(1, lists);
lists.Clear();
lists.Add("foobar");
likeListDict.Add(2, lists);
At the likeListDict.Add(1, lists) part, the "hello" and "world" get added in to key 1. But once I do the lists.Clear(), and add in the key 2 to likeListDict, both key 1 and 2 now have "foobar". How do I stop this (call by reference) and make it call by value?
There is no concept of "call by reference" or "call by value". List<T> is a reference type, so whatever you do to a given reference will be visible anywhere in the program where that reference exists.
What you want to do is create a new list instead of calling lists.Clear();
Dictionary<int, List<string>> likeListDict = new Dictionary<int, List<string>>();
List<string> lists = new List<string>();
lists.Add("hello");
lists.Add("world");
likeListDict.Add(1, lists);
lists = new List<string>();
lists.Add("foobar");
likeListDict.Add(2, lists);
Make a second list, don't try to reuse the first list. You're storing a reference to lists in the Dictionary, so adding it twice results in the same reference being in your dictionary twice, so changes to your list are reflected in both entries in the dictionary.
Ex:
public static void Main()
{
var likeListDict = new Dictionary<int, List<string>>();
var lists = new List<string> {"hello", "world"};
likeListDict.Add(1, lists);
var secondList = new List<string> {"foobar"};
likeListDict.Add(2, secondList);
}

Categories