Find index of item from string array containing comma separated values - c#

Below is my string array :
string[] arr = {
"region1.mp3,region1-sub.mp3,region1-sub1.mp3,region2-sub.mp3",
"region2.mp3,region2-Sub1.mp3",
"region3.mp3"
};
Below is my value which I am trying to search in above string array and get index:
string searchItem = "region1-sub1.mp3";
This is how I am trying to search but getting -1 (-1 indicates search not found I guess):
int index = Array.FindIndex(arr, t => t == searchItem); // -1
I understand that because my records in string array are comma separated that is why this search is failing.
So any other method which can help me find index without looping and generating new string array?
Expected Output : 0

You want to split every string by comma:
int index = Array.FindIndex(arr, t => t.Split(',').Contains(searchItem));
This works even if the string doesn't contain a comma.

This will you give you your desired output.
int index = Array.FindIndex(arr, t => t.Contains(searchItem));

int index = Array.FindIndex(arr, t => t.Contains(searchItem));
This returns 0.

Related

Strange? issue with cast of List<T> to array

I've defined List
private class Kamery
{
public int iIndeks;
public string strNazwa;
public Kamery(int Indeks, string Nazwa)
{
iIndeks = Indeks;
strNazwa = Nazwa;
}
}
List<Kamery> lKamery = new List<Kamery>();
I'd like to cast searched list of names to string array like:
string[] strNazwa = (string)lKamery.Find(item => item.iIndeks == iIndeks).strNazwa.ToArray();
But compiler says Cannot convert type 'char[]' to 'string'
Why? How it needs to be done?
I think you want:
string[] strNazwa = lKamery.Where(item => item.iIndeks == iIndeks)
.Select(item => item.strNazwa)
.ToArray();
That will give you a string array that contains each of the strNazwa values from the list for items that meet the Where condition.
Here's what your original code was doing:
string[] strNazwa = (string)
// get the one item that matches the condition
lKamery.Find(item => item.iIndeks ==Indeks)
// get the strNazwa property from that one item
.strNazwa
// return the string as a char array
.ToArray();
When you try to cast the char[] to a string it fails since you can't cast it. You can create a string from a character array but not via a cast.
I think your problem is that .Find returns only 1 value , the first match in the list.
https://msdn.microsoft.com/en-us/library/x0b5b5bc(v=vs.110).aspx
This value will be a string and by using .toArray , you are converting that string to a char[ ] and then trying to cast it back to string.
I'm not that good at c# , so the generic solution would be:
Declare the array, do a foreach and every time the id matches put the name into the array and inc the index. This limits it somewhat as you have to have a fixed size, would probably be better to use List instead.

First index before a position

I have a string and index in that string, and want to get the first position of a substring before that index.
e.g., in string:
"this is a test string that contains other string for testing"
Is there a function that:
Returns 42, given the sub-string "string" and the start position 53; and
Returns 15, given the sub-string "string" and the start position 30?
Like IndexOf() where you can start, lastIndexOf also gives you a place to start from going backwards
var myString = "this is a test string that contains other string for testing";
var lastIndexOf = myString.LastIndexOf("string", 30);
Reports the zero-based index position of the last occurrence of a specified string within this instance. The search starts at a specified character position and proceeds backward toward the beginning of the string.
Try something like:
var res = yourString.Substring(0, index).LastIndexOf(stringToMatch);
So you want the last index before a given index...
var myString = "this is a test string that contains other string for testing";
myString = String.SubString(0, 53);
var lastIndexOf = myString.LastIndexOf("string");
You can simply take the substring from 0 to index and on this substring ask for the last index of it
YourString.substring(0,index).LastIndexOf("string");
I know I am late to the party but this is the solution that I am using:
public static int FindIndexBefore(this string text, int startIndex, string searchString)
{
for (int index = startIndex; index >= 0; index--)
{
if (text.Substring(index, searchString.Length) == searchString)
{
return index;
}
}
return -1;
}
I tested it on your example and it gave the expected results.

C# LINQ: How is string("[1, 2, 3]") parsed as an array?

I am trying to parse a string into array and find a very concise approach.
string line = "[1, 2, 3]";
string[] input = line.Substring(1, line.Length - 2).Split();
int[] num = input.Skip(2)
.Select(y => int.Parse(y))
.ToArray();
I tried remove Skip(2) and I cannot get the array because of non-int string. My question is that what is the execution order of those LINQ function. How many times is Skip called here?
Thanks in advance.
The order is the order that you specify. So input.Skip(2) skips the first two strings in the array, so only the last remains which is 3. That can be parsed to an int. If you remove the Skip(2) you are trying to parse all of them. That doesn't work because the commas are still there. You have splitted by white-spaces but not removed the commas.
You could use line.Trim('[', ']').Split(','); and int.TryParse:
string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int i = 0;
int[] num = input.Where(s => int.TryParse(s, out i)) // you could use s.Trim but the spaces don't hurt
.Select(s => i)
.ToArray();
Just to clarify, i have used int.TryParse only to make sure that you don't get an exception if the input contains invalid data. It doesn't fix anything. It would also work with int.Parse.
Update: as has been proved by Eric Lippert in the comment section using int.TryParse in a LINQ query can be harmful. So it's better to use a helper method that encapsulates int.TryParse and returns a Nullable<int>. So an extension like this:
public static int? TryGetInt32(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
Now you can use it in a LINQ query in this way:
string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int[] num = input.Select(s => s.TryGetInt32())
.Where(n => n.HasValue)
.Select(n=> n.Value)
.ToArray();
The reason it does not work unless you skip the first two lines is that these lines have commas after ints. Your input looks like this:
"1," "2," "3"
Only the last entry can be parsed as an int; the initial two will produce an exception.
Passing comma and space as separators to Split will fix the problem:
string[] input = line
.Substring(1, line.Length - 2)
.Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
Note the use of StringSplitOptions.RemoveEmptyEntries to remove empty strings caused by both comma and space being used between entries.
I think it would be better you do it this way:
JsonConvert.DeserializeObject(line, typeof(List<int>));
you might try
string line = "[1,2,3]";
IEnumerable<int> intValues = from i in line.Split(',')
select Convert.ToInt32(i.Trim('[', ' ', ']'));

Find string with most characters in array

I have an array of string, and would like to find the index of the string with the most characters. I would like to do this without a for-loop.
You can just use the Select overload that gives you the index, order by descending length and get the first value;
string[] strings = new string[]{ "one", "three", "two" };
var value = strings.Select ((val, ix) => new {len=val.Length, ix})
.OrderByDescending (x => x.len).FirstOrDefault();
Console.WriteLine ("Index of longest string is: " +
(value != null ? value.ix : -1));
Use a recursive function that takes a current string, the array of strings, the index of the current string, index of the current string in the array, and the current max char count.

How can I parse an integer and the remaining string from my string?

I have strings that look like this:
1. abc
2. def
88. ghi
I'd like to be able to get the numbers from the strings and put it into a variable and then get the remainder of the string and put it into another variable. The number is always at the start of the string and there is a period following the number. Is there an easy way that I can parse the one string into a number and a string?
May not be the best way, but, split by the ". " (thank you Kirk)
everything afterwards is a string, and everything before will be a number.
You can call IndexOf and Substring:
int dot = str.IndexOf(".");
int num = int.Parse(str.Remove(dot).Trim());
string rest = str.Substring(dot).Trim();
var input = "1. abc";
var match = Regex.Match(input, #"(?<Number>\d+)\. (?<Text>.*)");
var number = int.Parse(match.Groups["Number"].Value);
var text = match.Groups["Text"].Value;
This should work:
public void Parse(string input)
{
string[] parts = input.Split('.');
int number = int.Parse(parts[0]); // convert the number to int
string str = parts[1].Trim(); // remove extra whitespace around the remaining string
}
The first line will split the string into an array of strings where the first element will be the number and the second will be the remainder of the string.
Then you can convert the number into an integer with int.Parse.
public Tuple<int, string> SplitItem(string item)
{
var parts = item.Split(new[] { '.' });
return Tuple.Create(int.Parse(parts[0]), parts[1].Trim());
}
var tokens = SplitItem("1. abc");
int number = tokens.Item1; // 1
string str = tokens.Item2; // "abc"

Categories