I have a string array, I need to delete all elements until a specific index or get a new array of all elements from my specific index. I'm looking for a system function without loops.
my code for example:
string []myArray = {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}
int myIndex = Array.IndexOf(myArray, "DDD");
needed output :
string []myNewArray = {"EEE","FFF","GGG","HHH"}
Just use Skip in Linq
string []myArray = {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}
int myIndex = Array.IndexOf(myArray, "DDD");
var newArray = myArray.Skip(myIndex+1);
Of course this means only that the loop is hidden from your view, but it exits nevertheless inside the Skip method.
Also, the code above, will return the whole array if the search for the string is unsuccessful.
You can use Linq's SkipWhile
string[] myArray = { "AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH" };
var myNewArray = myArray.SkipWhile(x => x != "DDD").Skip(1).ToArray();
Arrays are a pretty "dumb" object, as they mostly just have methods that effectively describe themselves. What you'll want to do is make it Queryable (one of its methods), then use LINQ to do it.
string[] myarray = GimmeAStringArray();
int x = desiredIndexValue;
return myarray.AsQueryable().Where(t => myarray.IndexOf(t) > x);
You might not need to AsQueryable() it to do that.
there is another simple way to do that using arrayList:
you can use method arraylist.RemoveRange(start index, last index)
public static void Main()
{
string[] array = new string[] {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"};
List<string> list = new List<string>(array);
list.RemoveRange(0,list.IndexOf("DDD")+1);
foreach (string str in list)
{
Console.WriteLine(str);
}
}
output of program will be :
EEE
FFF
GGG
HHH
Related
So I know in Python you can have
thislist = ["apple", "banana", "cherry"] + ['taco'] *2
which will print out ['apple', 'banana', 'cherry', 'taco', 'taco']. Is there something similar in c# that can be used? I am writing a list and will have 20-30 of the same item in the list and I just want to save myself some work and possibly make it look clean.
Is not similar as Python but you could use:
List<string> strList = new List<string>();
strList.AddRange(Enumerable.Repeat("Hello", 50));
This will add "Hello" 50 times.
Try this (it is just a tip)
var x=["apple", "banana", "cherry"];
var y= MultArray("taco",2);
var result=ConcatArrays(x,y);
To create array of the same strings:
public static string[] MultArray(string str, int quantity)
{
var z = new string[quantity];
for(i=0, i<quantity, i++)
{
z[i]=str;
}
return z;
}
to concat
public static string[] ConcatArrays(string[] x, string[] y)
{
var z = new string[x.Length + y.Length];
x.CopyTo(z, 0);
y.CopyTo(z, x.Length);
return z;
}
I believe you can create a generic function if you have a lot of arrays.
Another way is to convert arrays to list and use the list functions. In the end you will have to convert a list to array. But it is much more expensive.
New to coding and this is probably fairly basic, but help would be appreciated.
I believe I have an issue with how I am adding note2 to majorScale[]. Once the block is finished, it returns System.String[] rather than the actual array I was expecting.
public static string[] majorScaleOfNote (string tonic)
{
string[] intervals = { "M2", "M3", "P4", "P5", "M6", "M7" };
string[] majorScale = new string[7];
majorScale [0] = tonic;
foreach (string interval in intervals) {
string note2 = intervalUpToNote (tonic, interval);
majorScale[Array.IndexOf (intervals, interval) + 1] = note2;
}
return majorScale;
}
I've narrowed down the problem to something in the string[] majorScale. When I run something without that, it produces the correct result. Something like this:
Console.WriteLine (tonic);
string[] intervals = { "M2", "M3", "P4", "P5", "M6", "M7" };
foreach (string interval in intervals) {
string note2 = intervalUpToNote (tonic, interval);
Console.WriteLine (note2);
}
Is there an problem with the way I am adding note2 to majorScale? Or is there another issue? Any help is appreciated!
The problem is most probably not in this method, but in using a result of method execution in a calling method.
I guess, you later try to Console.WriteLine the contents of its array like this:
string[] result = majorScaleOfNote("M1");
Console.WriteLine(result);
You cannot output arrays this way.
C# applies .ToString() to all objects in order to get their string representation. Arrays do not have its own ToString() method, which results in the most base class Object's .ToString() being called. It simply does the following:
public virtual String ToString()
{
return GetType().ToString();
}
That's why, it outputs its type which results to System.String[].
If you want to output all elements of an array, you could try to iterate through it yourself and output strings one by one:
string[] result = majorScaleOfNote("M1");
foreach (var note in result)
Console.WriteLine(result);
or you can use String.Join method, which joins a string using a provided separator:
string[] result = majorScaleOfNote("M1");
Console.WriteLine(string.Join(", ", result));
I have a generic list of string[] arrays, and I need to build a list of strings with all possible combinations of the items in those arrays. I'm having a hard time wrapping my head around the best method.
so:
List mylist = new List; // I then populate this from the db...
The contents of mylist looks like this:
Buildings ||| Facilities ||| Fields ||| Files; Groups; Entity; ||| Controllers; FX; Steam;
The pipes " ||| " separate each string array in mylist, the semicolons are delimiters representing the items within each of those arrays. So the arrays have a minimum length of 1, and a max of N. I need to build a list of hyphen "---" separated strings with all possible combinations of the above, but staying in the order that they are in within the list. So using the above as an example, I would come up with this list of strings:
Buildings---Facilities---fields---Files---Controllers
Buildings---Facilities---fields---Groups---Controllers
Buildings---Facilities---fields---Entity---Controllers
Buildings---Facilities---fields---Files---Fx
Buildings---Facilities---fields---Groups---Fx
Buildings---Facilities---fields---Entity---Fx
Buildings---Facilities---fields---Files---Steam
Buildings---Facilities---fields---Groups---Steam
Buildings---Facilities---fields---Entity---Steam
If the 3rd array in the list had 2 items, instead of 1 ("Fields") - we'd have a list of 18 strings instead of 9 (3x3x2).
I tried using for loops, knowing which array had the largest length, and loop through each list item, but I just couldn't get it to work. Sleeping on it didn't really help.
anyone?
I would try recursion:
private void button1_Click(object sender, EventArgs e)
{
List<string[]> strs = new List<string[]>();
strs.Add(new string[] {"Buildings"});
strs.Add(new string[] {"Facilities"});
strs.Add(new string[] {"Fields"});
strs.Add(new string[] {"Files", "Groups", "Entity"});
strs.Add(new string[] {"Controllers", "FX", "Steam"});
List<string> list = AddStringsToList(strs, 0);
}
List<string> AddStringsToList(List<string[]> list, int level)
{
List<string> listOfStrings = new List<string>();
if (level == list.Count - 1)
{
foreach (string s in list[level])
{
listOfStrings.Add(s);
}
}
else if(level<list.Count-1)
{
List<string> list1 = AddStringsToList(list, level + 1);
foreach (string s in list[level])
{
foreach(string s1 in list1)
listOfStrings.Add(s + "---" + s1);
}
}
return listOfStrings;
}
Tested and it works!
I think this might do what you're looking for:
static IEnumerable<string> Combinations(IEnumerable<IEnumerable<string>> items)
{
return items.Aggregate((outs, ins) => outs.SelectMany(o => ins.Select(i => o + "---" + i)));
}
And here is an example usage
static void Main(string[] args)
{
IEnumerable<IEnumerable<string>> items = new string[][]
{
new [] { "Buildings" },
new [] { "Facilities" },
new [] { "Fields" },
new [] { "Files", "Groups", "Entity" },
new [] { "Controllers", "FX", "Steam" }
};
foreach (var c in Combinations(items))
Console.WriteLine(c);
Console.ReadLine();
}
For each set of possibilities, it takes all the strings it has so far (for example "Buildings---Facilities---fields---Files", "Buildings---Facilities---fields---Entity" etc), and then for each possibility (eg { "Controllers", "FX", "Steam"}) it appends that possibility to the the output string to get a new set of output strings. The aggregation iterates this process starting at just the possibilities for the first element as the output strings, and then repeating this "Cartesian product" successively until all the input is consumed.
Edit
For reference this is the output from the sample program:
Buildings---Facilities---Fields---Files---Controllers
Buildings---Facilities---Fields---Files---FX
Buildings---Facilities---Fields---Files---Steam
Buildings---Facilities---Fields---Groups---Controllers
Buildings---Facilities---Fields---Groups---FX
Buildings---Facilities---Fields---Groups---Steam
Buildings---Facilities---Fields---Entity---Controllers
Buildings---Facilities---Fields---Entity---FX
Buildings---Facilities---Fields---Entity---Steam
I'd like to point out that this solution is quite efficient. It doesn't use recursion, which makes it particularly efficient for cases with long chains. Also, it evaluates the result lazily which is much more memory efficient if you're dealing with many result combinations (remember these combinations can grow exponentially with the chain length).
Let's produce this instead:
Buildings---Facilities---fields---Files---Controllers
Buildings---Facilities---fields---Files---Fx
Buildings---Facilities---fields---Files---Steam
Buildings---Facilities---fields---Groups---Controllers
Buildings---Facilities---fields---Groups---Fx
Buildings---Facilities---fields---Groups---Steam
Buildings---Facilities---fields---Entity---Controllers
Buildings---Facilities---fields---Entity---Fx
Buildings---Facilities---fields---Entity---Steam
First, let's assume the data from the DB is in this format:
List<List<string>> dataFromDb;
It doesn't matter if some of the inner collections only have one value. Then something like this should do the trick:
void ConcatString(string prefix, int index, List<List<string>> collection, List<string> output)
{
if(index == collection.Count)
{
output.Add(prefix);
return;
}
var subCollection = collection[index];
foreach(var str in subCollection)
{
string newPrefix = ((prefix.Length > 0)? "---" : "") + str;
ConcatString(newPrefix, index+1, collection, output);
}
}
Called like:
var output = new List<string>();
ConcatString("", 0, dataFromDb, output);
The list you're looking for should be in output. Now, please note, I haven't run this (heck, I haven't even compiled this) so you'll need to debug it but it should get you going in the correct direction at a minimum.
I need to convert a string of comma separated integers into a list of integers.
What is the best way to do this?
I can do it below but am worried about the performance - Is there a better more efficient way to do this?
public IEnumerable<int> GetListOfIds()
{
string Ids = "1,4,5,7,12"; // would be passed into method
List<int> _result = Ids.Split(',')
.ToList()
.Select(item => int.Parse(item))
.ToList();
return _result;
}
There's no need to call ToList, but otherwise your code looks fine:
public IEnumerable<int> GetListOfIds(string ids)
{
return ids.Split(',').Select(item => int.Parse(item));
}
You may also want to consider adding error handling in case the input string is invalid:
public IEnumerable<int> GetListOfIds(string ids)
{
foreach (string part in ids.Split(','))
{
int x;
if (!int.TryParse(part, out x))
{
throw new ArgumentException(
string.Format("The value {0} cannot be parsed as an integer.", part),
"ids");
}
else
{
yield return x;
}
}
}
You may at least omit first ToList() statement - so it will be
List<int> _result = Ids.Split(',').Select(item => int.Parse(item)).ToList();
You can probably loop on the split result and do a yield return int.Parse... but I would not expect big differences unless you have really many items in the original string.
Use the Stringify.Library nuget package
Example 1 (Default delimiter is implicitly taken as comma)
var ids = "1, 4, 5, 7, 12";
var splitComma = new StringConverter().ConvertTo<List<int>>(ids);
Example 2 (Specifying the delimiter explicitly)
var ids = "1; 4; 5; 7; 12";
var splitColon = new StringConverter().ConvertTo<List<int>>(ids, new ConverterOptions { Delimiter = ';' });
I have a multiselect dropdown called ID that submits ID=1,2,3 which I need parsed into an integer array to do a Contains() on in a filter method. At the moment I use:
string[] ids = Request["ID"].Split(',');
Which I don't really like because its slower to compare string than int. Any suggestions?
Request["ID"].Split(',').Select(x=>int.Parse(x)).ToArray();
Of course, this will throw if any of the resulting numeric strings are not "parseable" (does such a word exist?).
It depends on how many times you will look up in the array if converting to ints are faster or the string comparison is faster.
HashSet<int> ids = new HashSet<int>(from s in Request["ID"].Split(',')
select int.Parse(s));
But probably the fastest if you have many id:s will be to create a HashSet<string>:
HashSet<string> = new HashSet<string>(string[] ids = Request["ID"].Split(','));
int[] ids = Request["ID"].Split(',').Select(Convert.ToInt32).ToArray();
First:
string[] arr = Request["ID"].Split(',')
Then:
Array.ConvertAll(arr, s => Int32.Parse(s));
Array.ConvertAll(arr, Int32.Parse);
arr.Select(s => Int32.Parse(s));
arr.Select(Int32.Parse);
Then:
new HashSet<int>(result);
(the most fast container to perform Contains())
See also:
Convert string[] to int[] in one string of code using LINQ
Which one is faster in processing and conversion int.Parse(), int.TryParse(), Convert.Int32()
If you don't have linq, you can:
string[] ids = Request["ID"].Split(',');
int[] items = new int[ids.Length];
for(int i = 0; i<ids.Length; i++)
{
items[i] = int.Parse(ids[i]);
}