Adding Items to a string array - c#

I need a way to prepend items on to an existing string array, such that:
string[] dirParams = null;
if (Request.Params["locationDirection_0"] != "")
{
dirParams = Request.Params["locationDirection_0"].Split(',');
}
if (Request.Params["locationDirection_1"] != "")
{
dirParams = Request.Params["locationDirection_1"].Split(',');
}
if (Request.Params["locationDirection_2"] != "")
{
dirParams = Request.Params["locationDirection_2"].Split(',');
}
if (Request.Params["locationDirection_3"] != "")
{
dirParams = Request.Params["locationDirection_3"].Split(',');
}
will give me a string array of about 4 items (assuming none of the requests coming in are empty)
whats the easiest way to do this, I thought of using a list and or a dictonary, neither will work for what I want to do, string array is all I want.

Use a list instead:
List<string> dirParams = new List<string>();
if (Request.Params["locationDirection_0"] != "")
{
dirParams.AddRange(Request.Params["locationDirection_0"].Split(','));
}
if (Request.Params["locationDirection_1"] != "")
{
dirParams.AddRange(Request.Params["locationDirection_1"].Split(','));
}
if (Request.Params["locationDirection_2"] != "")
{
dirParams.AddRange(Request.Params["locationDirection_2"].Split(','));
}
if (Request.Params["locationDirection_3"] != "")
{
dirParams.AddRange(Request.Params["locationDirection_3"].Split(','));
}

Use a List<string> and then the ToArray() method to convert it into a string[].

Build your items in a List<string> then use LINQ's .ToArray () to convert it into an array.

How about using Linq?
var dirParam = Enumerable.Range(0, 4)
.Select(i => Request.Params["locationDirection_" + i])
.Where(s => !String.IsNullOrEmpty(s))
.SelectMany(s => s.Split(','))
.ToArray();

Related

Get all fixed drives names to a string array

I want to get all the fixed drives names as a string array to give names for radio buttons..
this is the code i have used..
var drvs = System.IO.DriveInfo.GetDrives();
int hdcount = 0;
string[] drivenames;
foreach (var drv in drvs)
{
if (drv.DriveType == System.IO.DriveType.Fixed)
{
drivenames[hdcount] = drv.Name;
hdcount++;
}
}
But this code does not work.
it says "Error 1 Use of unassigned local variable 'drivenames'"
whats the wrong with my code ? how can i fix this ?
You have just declared the array string[] drivenames;, but you need to allocate the space required for the drive names, string[] drivenames = new string[fixedDriveCount]; but this is a bit unpractical because you should know the number of fixed drives before. Also there are more powerfull objects to store a collection of items that don't require to know the number of items to store in the collection before hand. I suggest to use a List<string> instead
var drvs = System.IO.DriveInfo.GetDrives();
List<string> drivenames = new List<string>();
foreach (var drv in drvs)
{
if (drv.DriveType == System.IO.DriveType.Fixed)
{
drivenames.Add(drv.Name);
}
}
int hdcount = drivenames.Count;
And with Linq you could shorten everything to
var drvs = DriveInfo.GetDrives()
.Where(x => x.DriveType == DriveType.Fixed)
.Select(k => k.Name).ToList();
// and then use the result to initialize a listbox (for example)
listBox1.DataSource = drvs;
Here is how to do it Linqy
String []dArray = System.IO.DriveInfo.GetDrives()
.Where(x => x.DriveType == DriveType.Fixed)
.Select(d => d.Name).ToArray();
or
List<string> dList = System.IO.DriveInfo.GetDrives()
.Where(x => x.DriveType == DriveType.Fixed)
.Select(d => d.Name).ToList();
You missed to initialize your string array. You can do this by using the number of drives.
Try
var drvs = System.IO.DriveInfo.GetDrives();
int hdcount = 0;
string[] drivenames = new string[drvs.Count()];
foreach (var drv in drvs)
{
if (drv.DriveType == System.IO.DriveType.Fixed)
{
drivenames[hdcount] = drv.Name;
hdcount++;
}
}

Iterate over array of strings and replace if exists

I am trying to iterate over an array of strings and check/replace if any of the strings exist in the input string. Using LINQ, this is what i have so far.
string input = "/main/dev.website.com"
string[] itemsToIgnore = { "dev.", "qa.", "/main/" };
string website = itemsToIgnore
.Select(x =>
{ x = input.Replace(x, ""); return x; })
.FirstOrDefault();
When i run this, nothing actually happens and my input string stays the same?
string website = itemsToIgnore
.Aggregate(input, (current, s) =>
current.StartsWith(s) ? current.Replace(s, string.Empty) : current);
and without Linq
foreach (var part in itemsToIgnore)
{
if (website.StartsWith(part))
{
website = website.Replace(part, string.Empty);
}
}

Sorting strings in C#

I have a delimited string that I need sorted. First I need to check if 'Francais' is in the string, if so, it goes first, then 'Anglais' is next, if it exists. After that, everything else is alphabetical. Can anyone help me? Here's what I have so far, without the sorting
private string SortFrench(string langs)
{
string _frenchLangs = String.Empty;
string retval = String.Empty;
_frenchLangs = string.Join(" ; ",langs.Split(';').Select(s => s.Trim()).ToArray());
if (_frenchLangs.Contains("Francais"))
retval += "Francais";
if (_frenchLangs.Contains("Anglais"))
{
if (retval.Length > 0)
retval += " ; ";
retval += "Anglais";
}
//sort the rest
return retval;
}
Someone liked my comment, so figured I'd go ahead and convert that into your code:
private string SortFrench(string langs)
{
var sorted = langs.Split(';')
.Select(s => s.Trim())
.OrderByDescending( s => s == "Francais" )
.ThenByDescending( s => s == "Anglais" )
.ThenBy ( s => s )
.ToArray();
return string.Join(" ; ",sorted);
}
My syntax may be off slightly as I've been in the Unix world for awhile now and haven't used much LINQ lately, but hope it helps.
Here's what I came up with. You could change the .Sort() for a OrderBy(lang => lang) after the Select, but I find it's cleaner that way.
public string SortLanguages(string langs)
{
List<string> languages = langs.Split(';').Select(s => s.Trim()).ToList();
languages.Sort();
PlaceAtFirstPositionIfExists(languages, "anglais");
PlaceAtFirstPositionIfExists(languages, "francais");
return string.Join(" ; ", languages);
}
private void PlaceAtFirstPositionIfExists(IList<string> languages, string language)
{
if (languages.Contains(language))
{
languages.Remove(language);
languages.Insert(0, language);
}
}
You should use a custom comparer class
it will allow you to use the built in collection sorting functions, or the linq OrderBy using your own criteria
Try this:
private string SortFrench(string langs)
{
string _frenchLangs = String.Empty;
List<string> languages = langs
.Split(';')
.Select(s => s.Trim())
.OrderBy(s => s)
.ToList();
int insertAt = 0;
if (languages.Contains("Francais"))
{
languages.Remove("Francais");
languages.Insert(insertAt, "Francais");
insertAt++;
}
if(languages.Contains("Anglais"))
{
languages.Remove("Anglais");
languages.Insert(insertAt, "Anglais");
}
_frenchLangs = string.Join(" ; ", languages);
return _frenchLangs;
}
All can be done in single line
private string SortFrench(string langs)
{
return string.Join(" ; ", langs.Split(';').Select(s => s.Trim())
.OrderBy(x => x != "Francais")
.ThenBy(x => x != "Anglais")
.ThenBy(x=>x));
}
Sorting alphabetically is simple; adding .OrderBy(s => s) before that .ToArray() will do that. Sorting based on the presence of keywords is trickier.
The quick and dirty way is to split into three:
Strings containing "Francais": .Where(s => s.Contains("Francais")
Strings containing "Anglais": .Where(s => s.Contains("Anglais")
The rest: .Where(s => !francaisList.Contains(s) && !anglaisList.Contains(s))
Then you can sort each of these alphabetically, and concatenate them.
Alternatively, you can implement IComparer using the logic you described:
For strings A and B:
If A contains "Francais"
If B contains "Francais", order alphabetically
Else
If B contains "Francais", B goes first
Else
If A contains "Anglais"
If B contains "Anglais", order alphabetically
Else, A goes first
Else, order alphabetically
There may be room for logical re-arrangement to simplify that. With all that logic wrapped up in a class that implements IComparer, you can specify that class for use by .OrderBy() to have it order your query results based on your custom logic.
You can also use Array.Sort(yourStringArray)
This code creates a list of the languages, sorts them using a custom comparer, and then puts the sorted list back together:
const string langs = "foo;bar;Anglais;Francais;barby;fooby";
var langsList = langs.Split(';').ToList();
langsList.Sort((s1, s2) =>
{
if (s1 == s2)
return 0;
if (s1 == "Francais")
return -1;
if (s2 == "Francais")
return 1;
if (s1 == "Anglais")
return -1;
if (s2 == "Anglais")
return 1;
return s1.CompareTo(s2);
});
var sortedList = string.Join(";", langsList);
Console.WriteLine(sortedList);
This way you can set any list of words in front:
private static string SortFrench(string langs, string[] setStartList)
{
string _frenchLangs = String.Empty;
List<string> list = langs.Split(';').Select(s => s.Trim()).ToList();
list.Sort();
foreach (var item in setStartList){
if (list.Contains(item))
{
list.Remove(setFirst);
}
}
List<string> tempList = List<string>();
tempList.AddRange(setStartList);
tempList.AddRange(list);
list = tempList;
_frenchLangs = string.Join(" ; ", list);
return _frenchLangs;
}

looping through an array of strings and converting to ints [duplicate]

This question already has answers here:
Change strings from one string to another in an array based on a condition
(8 answers)
Closed 9 years ago.
I have an array of strings, most of which are values "true" or "false" some are not and are to remain as are.
I wish to loop through the array and change any "true" or "false" to 1' or zero's
I have kind of started it, but am struggling with the syntax
string[] data = args.Trim().Split(',');
// Loop over strings
foreach (string s in data)
{
if(s == "true")
{
Convert.ToInt32(s)=1;????
}
else if(s == "false")
{
??????
}
}
please can someone offer some guidance
Perhaps with Linq:
string[] data = args.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => StringComparer.OrdinalIgnoreCase.Equals("true", s.Trim()) ? "1"
: StringComparer.OrdinalIgnoreCase.Equals("false", s.Trim()) ? "0" : s)
.ToArray();
Added the StringComparer.OrdinalIgnoreCase to show how you can ignore the case if desired.
Here's a demo with the sample string commented.
this,1,is,not,0
Write a function like this. You can then copy the "converted data" into a new List and return it as an array, or whatever.
public string[] GetData()
{
string[] data = args.Trim().Split(',');
List<string> returnData = new List<string>();
// Loop over strings
foreach (string s in data)
{
if(s == "true"){
returnData.Add("1");
}
else if(s == "false"){
returnData.Add("0");
}
else
returnData.Add(s);
}
return returnData.ToArray();
}
made a presumption you want an array of type string as you don't specify.
Other options as it's unclear what your going to do with the two types of data are to parse the values when you get them out, or split them up into two lists.
string[] rawDatas = GetData();
foreach(string rawData in rawDatas)
{
short iRawData;
if (Int16.TryParse(rawData, out iRawData))
{
if (iRawData == 1 || iRawData == 0)
{
//Add a bit
iRawData;
}
else
{
// add a string
rawData;
}
}
else
{
//add a string
rawData;
}
}
OR
public void GetData(out List<string> strings, out List<Int16> shorts)
{
string[] data = args.Trim().Split(',');
strings= new List<string>();
shorts = new List<Int16>();
// Loop over strings
foreach (string s in data)
{
if(s == "true"){
shorts.Add(1);
}
else if(s == "false"){
shorts.Add(0);
}
else
returnData.Add(s);
}
}
OR
add to an array of object, though this will need casting back on the other side, which is inefficent (see boxing and unboxing)
public object[] GetData()
{
string[] data = args.Trim().Split(',');
List<object> returnData = new List<object>();
// Loop over strings
foreach (string s in data)
{
if(s == "true"){
returnData.Add(1);
}
else if(s == "false"){
returnData.Add(0);
}
else
returnData.Add(s);
}
return returnData.ToArray();
}
if you just want to do 0 and 1 than
string[] data = args.Trim().Split(',');
int[] a = new int[data.length];
// Loop over strings
int count=0;
foreach (string s in data)
{
if(s == "true"){
int a[count] = 1;
}
else if(s == "false"){
int a[count]=0;
}
else
{
a[count] = Convert.ToInt32(s);
}
count++;
}
or with linq
var intlst = data.
Select(input => input == "true" ? 1 :
(input == "false" ? 0 : Convert.ToInt32(input)));
Try this:
var result = data.Select(input => input == "true" ? 1 : (input == "false")? 0 : -1);
You can do this by simple for loop:
List<string> newArgs = new List<string>();
for (int i = 0; i <= args.Length - 1; i++)
{
newArgs.Add(args[i] == "true" ? "1"
: args[i] == "false" ? "0"
: args[i]);
}
Or by using linq which will internally use extension object to iterate through the collection.
Well the problem that I can see you running into is holding the variables themselves without creating a new array. When you type the line
string[] data = args.Trim().Split(',');
you are declaring that the variables within that array are of type string. If you wish to convert them to integers you will need to create a new array of integers or undefined type. I think you are using C# which I believe the code for multiple types in an array is
object[]
In that case you would do something like
object[] data = args.Trim().Split(',');
foreach(string s in data){
if(s == "true"){
s = 1;
Convert.ToInt32(s);
}
else if(s == "false"){
s = 0;
Convert.ToInt32(s);
}
}

Change the foreach loop into the LINQ query

I stuck in an easy scenario. I have a List<string> object, all of its items has the body of:
item_1_2_generatedGUID //generatedGUID is Guid.NewGuid()
but there may be much more numbers
item_1_2_3_4_5_generatedGUID etc
now, I'm wondering how to change that loop into the LINQ's query. Any ideas ?
string one = "1"; //an exaplme
string two = "2"; //an exaplme
foreach (var item in myStringsList)
{
string[] splitted = item.Split(new char[] { '_' },
StringSplitOptions.RemoveEmptyEntries);
if(splitted.Length >= 3)
{
if(splitted[1] == one && splitted[2] == two)
{
resultList.Add(item);
}
}
}
var result = from s in lst
let spl = s.Split('_')
where spl.Length >= 3 && spl[1] = one && spl[2] == two
select s;
Try this:
var query = from item in myStringsList
let splitted = item.Split(new[] { '_' }, SSO.RemoveEmptyEntries)
where splitted.Length >= 3
where splitted[1] == one && splitted[2] == two
select item;
var resultList = query.ToList();
This is a different approach:
var items = myStringsList.
Where(x => x.Substring(x.IndexOf("_")).StartsWith(one+"_"+two+"_"));
You probably will need to add a +1 in the IndexOf, but I'm not sure.
What it does is:
Removes the first item (that's the substring for). In your example, it should be "1_2_3_4_5_generatedGUID"
Checks the string starts with what you are expecting. In your example: 1_2_
Edited: Added the pattern for anything at the first "position"
var result = items.Where(i => Regex.IsMatch(i, "^[^_]_1_2_"));

Categories