Parsing binary search as an arraylist in C# - c#

Is there any possible way to make this code shorter?
int? index = ListOfPeople.BinarySearch(searchBar.Text);
int? temp = int.TryParse(index.ToString(), out int i) ? (int?)1 : null;
MyPeopleGrid.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
MyPeopleGrid.Rows[i].Selected = true;
MyPeopleGrid.CurrentCell = MyPeopleGrid.Rows[i].Cells[0];

You seem to have seriously overcomplicated things, and you certainly should never convert a number to a string only to parse it back to a number.
int index = ListOfPeople.BinarySearch(searchBar.Text);
This will return a non-negative number when the item isn't found. It does not return int?, it returns int.
So now you can use it:
int index = ListOfPeople.BinarySearch(searchBar.Text);
if (index >= 0)
{
MyPeopleGrid.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
MyPeopleGrid.Rows[index].Selected = true;
MyPeopleGrid.CurrentCell = MyPeopleGrid.Rows[index].Cells[0];
}
else
{
// do something when the item isn't found
}

Related

Returning the smallest integer in an arrayList in C#

I recently got asked in a interview to create an method where the following checks are to be made:
Code to check if ArrayList is null
Code to loop through ArrayList objects
Code to make sure object is an integer
Code to check if it is null, and if not then to compare it against a variable containing the smallest integer from the list and if smaller then
overwrite it.
Return the smallest integer in the list.
So I created the following method
static void Main(string[] args)
{
ArrayList list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list.Add(5);
Program p = new Program();
p.Min(list);
}
private int? Min(ArrayList list)
{
int value;
//Code to check if ArrayList is null
if (list.Count > 0)
{
string minValue = GetMinValue(list).ToString();
//Code to loop through ArrayList objects
for(int i = 0; i < list.Count; i++)
{
//Code to make sure object is an integer
//Code to check if it is null, and if not to compare it against a variable containing the
//smallest integer from the list and if smaller overwrite it.
if (Int32.TryParse(i.ToString(), out value) || i.ToString() != string.Empty)
{
if (Convert.ToInt32(list[i]) < Convert.ToInt32(minValue))
{
minValue = list[i];
}
}
}
}
return Convert.ToInt32(GetMinValue(list));
}
public static object GetMinValue(ArrayList arrList)
{
ArrayList sortArrayList = arrList;
sortArrayList.Sort();
return sortArrayList[0];
}
I think the above is somewhat correct, however am not entirely sure about 4?
I think The following logic may help you. It is simpler than the current and are using int.TryParse() for parsing, which is better than Convert.To..() and int.Parse() Since it has some internal error handling and hence it will will not throw any exception for invalid input. If the input is invalid then it gives 0 to the out variable and returns false, From that we can assume the conversion failed. See the code for this:
var arrayMin = listOfInt;
int currentNum = 0;
int yourNum = int.MaxValue;
bool isSuccess = true;
foreach (var item in listOfInt)
{
if (int.TryParse(item.ToString(), out currentNum) && currentNum <= yourNum)
{
yourNum = currentNum;
}
else
{
isSuccess = false;
break;
}
}
if(isSuccess)
Console.WriteLine("Minimum Number in the array is {0}",yourNum);
else
Console.WriteLine("Invalid input element found");
Simplistic version:
private int? Min(ArrayList list)
{
if (list == null || list.Count == 0) return null;
return list.Cast<int>().Min();
}

Split a string and convert one of the index as int

I have the following code:
static void Main(string[] args)
{
string prueba = "Something_2.zip";
int num;
prueba = prueba.Split('.')[0];
if (!prueba.Contains("_"))
{
prueba = prueba + "_";
}
else
{
//The code I want to try
}
}
The idea is that in the else I want to split the string after the _ and convert it to int, I did this like
num = Convert.ToInt16(prueba.Split('_')[1]);
but can I cast the split? for example num = (int)(prueba.Split('_')[1]);
Is it possible to do it that way? Or I have to use the Convert?
You Cannot cast string as integer, so you need to do some conversion:
I suggest you to use Int.TryParse() in this scenario.
Hence the else part will be like the following:
else
{
if(int.TryParse(prueba.Substring(prueba.LastIndexOf('_')),out num))
{
//proceed your code
}
else
{
//Throw error message
}
}
Convert the string to int like this:
var myInt = 0;
if (Int32.TryParse(prueba.Split('_')[1], out myInt))
{
// use myInt here
}
It's a string, so you'll have to parse it. You can use Convert.ToInt32, int.Parse, or int.TryParse to do so, like so:
var numString = prueba.Split('_')[1];
var numByConvert = Convert.ToInt32(numString);
var numByParse = int.Parse(numString);
int numByTryParse;
if(int.TryParse(numString, out numByTryParse))
{/*Success, numByTryParse is populated with the numString's int value.*/}
else
{/*Failure. You can handle the fact that it failed to parse now. numByTryParse will be 0 */}
string prueba = "Something_2.zip";
prueba = prueba.Split('.')[0];
int theValue = 0; // Also default value if no '_' is found
var index = prueba.LastIndexOf('_');
if(index >= 0)
int.TryParse(prueba.Substring(index + 1), out theValue);
theValue.Dump();
You could use a regular expression and avoid all the string splitting logic. If you need an explanation of the regex I've used see https://regex101.com/r/fW9fX5/1
var num = -1; // set to default value that you intend to use when the string doesn't contain an underscore
var fileNamePattern = new Regex(#".*_(?<num>\d+)\..*");
var regexMatch = fileNamePattern.Match("Something_2.zip");
if (regexMatch.Success)
{
int.TryParse(regexMatch.Groups["num"].Value, out num);
}

Pass string value created in one function as parameter to function

I have a function called ValidColumns that, when finished will contain a string of id values joined by the pipe character "|."
private bool ValidColumns(string[] curGlobalAttr, int LineCount)
{
//test to see if there is more than 1 empty sku mod field in the imported file
string SkuMod = GetValue(curGlobalAttr, (int)GlobalAttrCols.SKU);
if(SkuMod =="")
ids += string.Join("|", OptionId);
}
What I want to do is take the ids string and pass it as a reference into another function to check to see if it contains duplicate values:
protected bool CheckForDuplicates(ref string ids)
{
bool NoDupes = true;
string[] idSet = ids.Split('|');
for (int i = 1; i <= idSet.Length - 1; i++)
{
if (idSet[i].ToString() == idSet[i - 1].ToString()) { NoDupes = false; }
}
return NoDupes;
}
But I am not sure how to do it properly? It seems so easy but I feel like I'm making this out to be much harder than it needs to be.
if (idSet[i].ToString() == idSet[i - 1].ToString())
You're only checking each value against the previous value. That would work if the values were sorted, but an easier method would just be to get a distinct list and check the lengths:
return (idSet.Length == idSet.Distinct().Count());
The second part of D Stanley's answer is what you want
public bool CheckForDuplicates(string value)
{
string[] split = value.Split('|');
return split.Length != split.Distinct().ToArray().Length;
}
You need a nested loop to do this which will look at each item and compare it to another item. This also will eliminate checking it against itself so it does not always return false.
In this we will track what we have already checked and only compare the new items against items after that slowly shrinking the second loop down in size to eliminate duplicate checks.
bool noDupes = true;
int currentItem = 0;
int counter = 0;
string[] idSet = ids.Split('|');
while(currentItem < idSet.Count)
{
counter = currentItem + 1;
while(counter < idSet.Count)
{
if(idSet[currentItem].ToUpper() == idSet[counter].ToUpper())
{
noDupes = false;
return noDupes;
}
counter ++;
}
currentItem ++;
}
return noDupes;
Edit:
It was pointed out an option I posted as an answer would always return false so I removed that option and adjusted this option to be more robust and easier to step through logically.
Hope this helps :)

How to cast string to int

I have a set of objects named something like this:
_1,_2,_3 .... _n
Isn't an array, just a bunch of objects uinto a custom control. I want to cast the name to an int. first I remove _, but If use
private void Superficie_MouseDown(object sender, MouseButtonEventArgs e)
{
int index = 0;
Shape myShape = ((Shape)sender);
string lcNombre = myShape.Name.Remove(0, 1);
//--------------------------------------------------------------------
// Those are my tryes
// Doesn't work because it must expect a nullable value
index = lcNombre as decimal;
// Doesn't work Can't convert string to int
index = (int)lcNombre;
//--------------------------------------------------------------------
if (index > 0)
{
bool lIsSelected = !Pieza.Superficies.Where(x=>x.Id == index).First().IsSelected;
Pieza.Superficies.Where(x => x.Id == index).First().IsSelected = lIsSelected;
if (lIsSelected)
myShape.Fill = new SolidColorBrush(SystemColors.HotTrackColor);
else
myShape.Fill = new SolidColorBrush(SystemColors.ControlLightLightColor);
}
}
How can I do to cast it ?
The most straightforward way is
index = int.Parse(lcNombre);
If you're not completely sure whether lcNombre is really an integer, you can use instead
int result;
bool isInt = int.TryParse(lcNobre, out result);
or in newer versions of .NET, you can declare the output variable like:
bool isInt = int.TryParse(lcNobre, out var result);
Finally you can use
index = Convert.ToInt32(lcNobre);
This approach (like int.Parse()) will throw a FormatException if the input value is not convertible to an integer.
You can also use the Convert static methods:
index = Convert.ToInt32(lcNombre);
MSDN Link: http://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.110).aspx
Error wise.. you may want to use TryParse.. as it returns true or false depending on a successful conversion:
int index;
if (int.TryParse(lcNombre, out index)) {
// conversion successful
}
else {
// couldn't convert
}
MSDN Link for int.TryParse: http://msdn.microsoft.com/en-us/library/f02979c7(v=vs.110).aspx
try this
int result=0;
Int32.TryParse(lcNombre,out result);
My favorite way to do this is to make an extension method as follows
public static class ExtensionMethods
{
public static int? AsInteger( this string str)
{
int value;
if ( int.TryParse( str, out value ) )
{
return value;
}
else
{
return null;
}
}
}
then you can this
index = lcNombre.AsInteger() ?? 0;
string strArr[] = myShape.Name.Split('_',StringSplitOptions.RemoveEmptyEntries)
int num;
int.TryParse(strArr[0],num);

A shorter way to write the following function in C#?

I have this function -
public int GetAvgResult()
{
var weeklyvalues=GetWeeklyValues();//gets list of weekly values.
if (weeklyvalues.Count == 0)
return 0;
return (weeklyvalues.Sum() / weeklyvalues.Count);
}
Is there a shorter way to write this using ?: or maybe something else ?
public double GetAvgResult()
{
// Assumes GetWeeklyValues() never returns null.
return GetWeeklyValues().DefaultIfEmpty().Average();
}
Do note that this returns a double , which I assume is what you really want (the average of a bunch of integers is logically not an integer). You can cast it to int if necessary, or if you want to stick with integer math all the way:
var seq = GetWeeklyValues().DefaultIfEmpty();
return seq.Sum() / seq.Count();
public int GetAvgResult()
{
var weeklyvalues = GetWeeklyValues();
return (weeklyvalues.Count != 0) ? (weeklyvalues.Sum() / weeklyvalues.Count) : 0;
}
or:
public int GetAvgResult()
{
return GetWeeklyValues().DefaultIfEmpty().Average();
}
public int GetAvgResult()
{
var weeklyvalues = GetWeeklyValues(); //gets list of weekly values.
return weeklyvalues.Count == 0 ? 0 : weeklyvalues.Sum() / weeklyvalues.Count;
}
That's as short as I'd attempt to make it. Is there a specific reason (other than code golf) you're trying for a low character count?
public int GetAvgResult()
{
var weeklyvalues = GetWeeklyValues();//gets list of weekly values.
return (weeklyvalues.Count == 0) ? 0 : (weeklyvalues.Sum() / weeklyvalues.Count );
}
public int GetAvgResult()
{
var weeklyvalues=GetWeeklyValues();//gets list of weekly values.
return weeklyvalues.Count == 0
? 0
: (weeklyvalues.Sum() / weeklyvalues.Count);
}

Categories