I am about to create a media player app, which will handle multiple playlists with of course, multiple songs. I've created an array of strings for the playlist names, they are stored in a text file. I load them with the File.ReadAllLines method like this:
1darray = File.ReadAllLines("textfilename.txt");
Every playlist has his own ID, I have a variable which stores the number of playlists.
I would like to read the Path of the songs with the same method, but it needs a 2D Array
2Darray[playlistID, songID]
As with the first method I didn't have to specify each element of the array, I will need now to specify the playlistID, and let the File.ReadAllLines method to fill the songID elements, but it doesn`t work like this:
2Darray[playlistID] = File.ReadAllLines("textfilename.txt");
it says Wrong number of indices inside []; expected 2.
How to deal with it?
Hope you understand my bad english!
Scan directory for playlist files: Directory class
Then enumerate the found files:
foreach (string filename in filenames)
{
// ...
}
Use each filename as the playlist ID:
Dictionary<string, string[]> playlists;
Collect each file's lines in the dictionary:
playlists.Add(filename, File.ReadAllLines(filename));
Get a specific playlist's entry (here, 4th of "dupestep.pl"):
playlists["dupestep.pl"][3] // index 3 is the 4th, because it's zero-based
From here on you should be able to implement whatever you need.
To abstract the list of playlists you can extract the list of keys to translate indices to filenames and viceversa:
playlists.Keys
While lots of people have suggested alternative solutions to your problem, nobody has yet explained what the original error means. What you need to understand is that C# makes a distinction between so-called jagged arrays and multidimensional arrays.
A jagged array is essentially an array of arrays. Declaring one looks like this:
int[][] jaggedArray = new int[4][];
This creates an array with four elements, and each of those four elements can be any array of int, of any size. This is why such arrays are called "jagged": some elements can be bigger than others. You can imagine it looking something like this:
[0, 1]
[5, 3, 2, 1]
[]
[9, 8, 7, 6, 5, 4, 2]
Note the jagged edge.
In keeping with the declaration, jagged arrays are accessed like this:
int[] element = jaggedArray[1];
int value = jaggedArray[1][2]; // equivalent to element[2]
Multidimensional arrays behave differently. A multidimensional array is declared like this:
int[,] multidimArray = new int[4, 4];
Unlike a jagged array, multidimensional arrays specify the size of both dimensions. All of the elements in such an array are of the same size. You can imagine it looking more like this:
[0, 1, 2, 3,
5, 4, 3, 2,
0, 0, 0, 0,
9, 8, 7, 4]
Multidimensional arrays must also be accessed somewhat differently. Unlike jagged arrays, which are effectively arrays of arrays, a multidimensional array is treated as a single, cohesive unit. Doing this:
int[] element = multidimArray[3];
...doesn't make any sense, because a multidimensional array isn't made up of smaller arrays. You can only access individual values within the array, and you do so like this:
int value = multidimArray[3, 2];
Note that you have to specify both indices within a single [] operator. These are the "coordinates" of the value you want, so to speak.
And this is the source of your error. You had a multidimensional array and you were attempting to access its individual array elements, which doesn't make any sense. To do what you were originally trying to do, you need to use a jagged array.
So basically you can map all playlists with their respective songs with a Dictionary>. Ofcourse this can be done better with classes and relations, however to keep it simple we will use the first example:
//get all playlists
string[] playLists = File.ReadAllLines("playLists.txt");
//storage
Dictionary<string, List<string>> playListsToSongsMap = new Dictionary<string, List<string>>();
//iterate the readed playlists
foreach (string playlist in playLists)
{
if (!playListsToSongsMap.ContainsKey(playlist))
{
playListsToSongsMap[playlist] = new List<string>();
}
//add songs to each playlist
playListsToSongsMap[playlist].AddRange(File.ReadLines("playListWithsongsPath"));
}
//get all playlits
List<string> allPlayLists = playListsToSongsMap.Keys.ToList();
//get all songs in a playlist
List<string> songsInPlaylist = playListsToSongsMap[allPlayLists[0]];
Related
I have a two dimensional array like this:
decimal[,] dataArray;
dataArray = new decimal[10, 20];
How can I get an onedimesional array that contains the values from one particular column?
Thanks.
There is no built-in API for slicing multidimensional arrays. Write a loop that goes through all rows, and harvests a specific column into a result array, or use LINQ to "fold" the loop:
var col = Enumerable.Range(0, 20).Select(r=>dataArray[3, r]).ToArray();
I'm working on a project. I've a situation here. I'm having arrays with similar names consider arr1, arr2, arr3, etc.
Now I know the array number which I'm supposed to use let it be 2. Is there any way in c# to make the array name dynamically through strings and use it.
Like in flash action script we can do
_root["arr"+i][0]
here i contains the array number to be used.
No - you cannot access variable names dynamically. You can use reflection to dynamically access properties, but not variables. I would use a List<int[]> like so:
List<int[]> arrList = new List<int[]> {arr1, arr2, arr3);
int[] arr = arrList[i-1]; // since lists and arrays use 0-based indexes
You can use a dictionary:
var dictionary = new Dictionary<string, int[]>();
dictionary.Add("array1", arr1);
dictionary.Add("array2", arr2);
dictionary.Add("array3", arr3);
var arr = dictionary[string.Format("array{0}", i)];
What you want is something what JavaScript or dynamic languages have, but their array types are rather associative arrays. To reach the functionality you want you can use Dictionary:
var arr1 = new int[] { 0, 1, 2, 3 };
var arr2 = new int[] { 0, 1, 2, 3 };
var arr3 = new int[] { 0, 1, 2, 3 };
var _root = new Dictionary<string, int[]>();
_root.Add("arr1", arr1);
_root.Add("arr2", arr2);
_root.Add("arr3", arr3);
for (int i = 1; i <= 3; i++)
{
int arrElem = _root["arr" + i][0];
}
Note the expression within the for loop, it's like what you were asking for.
use list for performing dynamic operations
As suggested in other answers the way to achieve the dynamism you're looking for is to put all of the arrays in a collection ( List<int[]> ) and then you can write more generalized code which operates on the contents of a given array without knowing which array it's operating on at compile time.
I have to add two int[] array in which a mian int[] array is intially vacant. I want to add the elements of another array in the main array . In the Main array, there would be more addtion that would be added in the last postion of the main array.
I have an array as -
var planetNotInRange = new int[7] ;
if(planetSign.Contains(tempFrind))
{
var result = planetSign.Select((b, k) => b.Equals(tempFrind) ? k : -1)
.Where(k => k != -1).ToArray();
// Here I want to add this result Array in to the planetNotInRange array,
// when ever there is some value in the result array.
}
this is in loop will give a number of array of integers. Now I want to concat in PLanetInRange Array one after other.
It sounds like you shouldn't have an array to start with, if you want to add elements to it. Once an array has been created, its size is fixed.
Use a List<int> instead, and you can use
list.AddRange(array);
I'd usually advise using lists (and other collection types) over arrays anyway. Arrays are useful, obviously, but they're somewhat more primitive and low-level than other collections.
Is there any way in c# to address a single row of a 2-dimensional array?
I want to be able to pass one-dimension of a 2 dimensional array as a parameter and sometimes I want to pass the whole 2-dimentional array.
You can use jagged arrays.
Example based on the code in Jagged Arrays (C# Programming Guide):
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];
// To pass the whole thing, use jaggedArray
// To pass one of the inner arrays, use jaggedArray[index]
Hey all. Is there a way to copy only a portion of a single (or better yet, a two) dimensional list of strings into a new temporary list of strings?
Even though LINQ does make this easy and more general than just lists (using Skip and Take), List<T> has the GetRange method which makes it a breeze:
List<string> newList = oldList.GetRange(index, count);
(Where index is the index of the first element to copy, and count is how many items to copy.)
When you say "two dimensional list of strings" - do you mean an array? If so, do you mean a jagged array (string[][]) or a rectangular array (string[,])?
I'm not sure I get the question, but I would look at the Array.Copy function (if by lists of strings you're referring to arrays)
Here is an example using C# in the .NET 2.0 Framework:
String[] listOfStrings = new String[7]
{"abc","def","ghi","jkl","mno","pqr","stu"};
String[] newListOfStrings = new String[3];
// copy the three strings starting with "ghi"
Array.Copy(listOfStrings, 2, newListOfStrings, 0, 3);
// newListOfStrings will now contains {"ghi","jkl","mno"}
FindAll will let you write a Predicate to determine which strings to copy:
List<string> list = new List<string>();
list.Add("one");
list.Add("two");
list.Add("three");
List<string> copyList = list.FindAll(
s => s.Length >= 5
);
copyList.ForEach(s => Console.WriteLine(s));
This prints out "three", because it is 5 or more characters long. The others are ignored.