I have a following array. I would like to find the index of the array which has M in the list so it should give me 2.
Array List
0 - > B, P , C
1 - > U, O, L
2 - > I, N, M
List<string>[] final = new List<string>[3];
I tried the following:
Array.IndexOf(final,"M")
But it does not work and it returns - 1 because second parameter is a list. Please do not use Linq
Array.IndexOf will traverse the one dimensional array and never find the search string since it will be comparing it to List<string>. You will have to traverse through the list of strings in you array:
public static int FindLetter(IList<string>[] arr, string search)
{
for(int i = 0; i < arr.Length; ++i)
{
if(arr[i].Contains(search))
{
return i;
}
}
return -1;
}
Since your "item to search" is a sub item of the list, you would first need to search each list.This can be done with Linq. Combining the result of Linq Query with Array.IndexOf, you can find the result as
var result = Array.IndexOf(final,final.FirstOrDefault(x => x.Contains(searchString)));
Just put some alternatives, if you wanted to ditch the array you could achieve the following with standard Linq methods
var final = new List<List<string>>();
var item = final.FirstOrDefault(x => x.Contains("M"));
// do stuff with item result
var index = final.FindIndex(x => x.Contains("M"));
// do stuff with the index
Keep in mind that you have a List<string> at each index of the array named final, so you just can't use Array.IndexOf, you have to search for the Key separately at every index. Following code is the working example of what you want to achieve:
public static int SearchKey(List<string>[] array, string key)
{
int index = 0;
foreach(List<String> i in array)
{
if(i.Contains(key))
{
return index;
}
index++;
}
return -1;
}
Related
I have an Array of twenty item slot that is empty.
For example we just use simple int array
public int[] Integers = new int[20];
Then I have a database that hold lot of items
public int[] Database = new int[] {
1, 2, 3, , ..., 1000
}
I would like to put some of items in database to my array
in Imperative I could just do:
// loop all my slots
for (int = 0; i < Integers.Length; i++) {
// If database index of i is empty, then done this loop
// correction: I'm putting null in case database type is not int
if(Database[i] == null) {
break;
}
// but when there's still something in database, fill it to current Integers[i]
else {
Integers[i] = Database[i]
}
}
But I wanted to make it in Linq, using Select and ForEach, however foreach doesn't have index i.
Note: I'm making a Inventory UI Item Slot in a game, so only twenty item inside the character could be seen in my UI at a time, it includes pagination also. I'm currently doing:
for (int i = 0; i < _slots.Count; i++)
_slots[i].SetItem(i < InventoryItems.Count ? InventoryItems[i] : null);
with setItem as the side effects;
Just omit nulls:
Integers = Database.Where(i => i != null).ToArray();
Note that, if you want to check for null in int array, you need to make it int? (nullable type):
public int?[] Integers = new int[20];
public int?[] Database = new int[] {
1, 2, 3, , ..., 1000
}
In fact, Integer can be int[], as you select non-null values :)
NOTE: With code you have you are very prone to index out of range exception, as you apply same indexing to both arrays.
I've been trying to figure out how to remove elements in my ArrayList where the value contains some text string.
My Array could look like this:
[0] "\"MAERSKA.CO\",N/A,N/A,N/A,N/A,N/A,N/A"
[1] "\"GEN.COABB.ST\",N/A,N/A,N/A,N/A,N/A,N/A"
[2] "\"ARCM.ST\",\"Arcam AB\",330.00,330.50,332.00,330.50,330.00"
And my ArrayList is created like this:
string stringToRemove = "NA";
ArrayList rows = new ArrayList(csvData.Replace("\r", "").Split('\n'));
So the question is how I delete all entries that contains "NA".
I have tried the RemoveAt or RemoveAll with several combinations of Contains but i cant seem to get the code right.
I do not want to make a new Array if it can be avoided.
Regards
Flemming
If you want to reduce your ArrayList before instantiate your variable, consider using LINQ:
ArrayList rows = new ArrayList(csvData.Replace("\r", "").Split('\n').Where(r => !r.Contains(stringToRemove)).ToList());
If you want to reduce your ArrayList after instantiation, you can try this:
for (int i = 0; i < rows.Count; i++)
{
var row = (string)rows[i];
if (row.Contains(stringToRemove))
{
rows.RemoveAt(i);
i--;
}
}
The following code creates a list as output containing all strings except "N/A":
var outputs = new List<string>();
foreach (var item in input)
{
var splitted = item.Split(',');
foreach (var splt in splitted)
{
if (splt != "N/A")
{
outputs.Add(splt);
}
}
}
The input is your array.
I couldn't find this anywhere else.
I've an array of lists:
public List<xmldata>[] XMLArrayList = new List<xmldata>[9999];
To initialize and insert a list into each position, i do the following:
for(int m=0; m< XList.XMLArrayList.Count(); m++)
{
XList.XMLArrayList[m] = new List<xmldata>();
}
But i would like to count how many elements there aren't null.
EX: Positions 0 to 5 have a List on them. But other positions not.
Tried a linq approach:
int count = XList.XMLArrayList.Count(x => x != null);
But it returns me the array size (9999). How can i count the non null elements on an array of lists ?
Ps: Already tried Dictionary and And List of List - this approach works best for achieving what i need.
Thanks.
Try this:
int count = XList.XMLArrayList.Count(x => x.Count()>0);
you can also do this
XList.XMLArrayList.Where(x => x.Any()).Count();
I have List of string. If the list contains that partial string then find out the index of that item. Please have a look on code for more info.
List<string> s = new List<string>();
s.Add("abcdefg");
s.Add("hijklm");
s.Add("nopqrs");
s.Add("tuvwxyz");
if(s.Any( l => l.Contains("jkl") ))//check the partial string in the list
{
Console.Write("matched");
//here I want the index of the matched item.
//if we found the item I want to get the index of that item.
}
else
{
Console.Write("unmatched");
}
You can use List.FindIndex:
int index = s.FindIndex(str => str.Contains("jkl")); // 1
if(index >= 0)
{
// at least one match, index is the first match
}
you can use this
var index = s.Select((item,idx)=> new {idx, item }).Where(x=>x.item.Contains("jkl")).FirstOrDefault(x=>(int?)x.idx);
Edit
In case when using a List<string>, FindIndex is better to use.
But in my defence, using FindIndex is not using LINQ as requested by OP ;-)
Edit 2
Should have used FirstOrDefault
This is how I was using it without Linq and wanted to shorten it so posted this question.
List<string> s = new List<string>();
s.Add("abcdefg");
s.Add("hijklm");
s.Add("nopqrs");
s.Add("tuvwxyz");
if(s.Any( l => l.Contains("tuv") ))
{
Console.Write("macthed");
int index= -1;
//here starts my code to find the index
foreach(string item in s)
{
if(item.IndexOf("tuv")>=0)
{
index = s.IndexOf(item);
break;
}
}
//here ends block of my code to find the index
Console.Write(s[index]);
}
else
Console.Write("unmacthed");
}
I have some strange problem where all my string arrays has the same value in the List.
Here is my code:
List<string[]> map_data = new List<string[]>();
string[] map_data_array = new string[11];
for(int i = 0; i < 2000; i++)
{
map_data_array = PopulateDataFromFile(); // it returns different data every call
map_data.Add(map_data_array); // store to List
}
map_data_array has always different data, I've verified that by placing the break point there and I've checked it.
The problem is that map_data has the value of all elements the same. And this value is the data that comes from function PopulateDataFromFile when the i is 1999.
What I am doing wrong? :/
That only happens if you place the same array into the list. As you did not give the code to PopulateDataFromFile we can only guess what happens. Make sure that the function returns a seperate array created with new each time.
You need to process your data in chunks since PopulateDataFromFile(); looks to be returning all of its data in one go (or as much as the array can fit). Using an extension method, you could do something like this: -
List<string[]> map_data = new List<string[]>();
foreach (var batch in PopulateDataFromFile().Batch(11))
{
map_data.Add((batch.ToArray());
}
Extension method: -
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int batchSize)
{
return items.Select((item, inx) => new { item, inx })
.GroupBy(x => x.inx / batchSize)
.Select(g => g.Select(x => x.item));
}
PopulateDataFromFile() is returning a String array with the same values.
In the loop everytime you just change the address of map_data_array , so that's why always the value will get changed to the newer data obtained from the method call. Reinitialize the string array everytime will help. It should look something like this
for(int i = 0; i < 2000; i++)
{
string[] map_data_array = PopulateDataFromFile(); // it returns different data every call
map_data.Add(map_data_array); // store to List
}
or if its confusing for you can you make it simple by
for(int i = 0; i < 2000; i++)
{
map_data.Add(PopulateDataFromFile()); // store to List
}