Count non null elements in an array of lists - c#

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();

Related

Searching a two dimensional object array in c#

I have declared a two-dimensional object array as
object[,] sectionOpenings = new object[20, 4];
The first column is populated with string types, whilst the remaining three columns are all integers.
I wish to do a quick search to find a row with a matching string in the first column and have tried this
var first = Array.Find(sectionOpenings, p => p == "homedepot");
I get the following error:
Error CS0411 The type arguments for method 'Array.Find(T[], Predicate)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Any suggestions?
You can alter your code a bit to get what you what:
var first = Array.Find(sectionOpenings, p => p[0] == "homedepot");
this will look in each array row, the first column p[0] == "homedepot"
edit:
my bad, I thought about jagged arrays
Well its not a one liner, but you can create a method like so:
public static int GetMatchingRow(object[,] myArr, string findMe)
{
for (int i = 0; i < myArr.GetLength(0); i++)
{
if (myArr[i, 0] is string && myArr[i, 0] as string == findMe)
return i;
}
return -1;
}
I would suggest changing to a dictionary to ensure type safety- like so:
var sectionOpenings = new Dictionary<string, List<int>>();
sectionOpenings.TryGetValue("homedepot", out var result);
However, if you are stuck using a 2D array, you'll likely have to do this in two steps. One, you'll have to find the matching column. Two, you'll have to retrieve the column. Something like this could work:
object[,] sectionOpenings = new object[20, 4];
var firstRowMatch = Enumerable
.Range(0, sectionOpenings.GetLength(0)) // Gets row indices
.Where(row => sectionOpenings[row, 0].ToString().Equals("homedepot"))
.First();
var result = Enumerable
.Range(0, sectionOpenings.GetLength(1)) // Gets column indices
.Select(column => sectionOpenings[firstRowMatch, column])
.ToArray();
With this example, you will likely have to add some type checks and null checks to make sure that this doesn't explode with a NullReferenceException.
This is adapted from returning a whole column from a 2D array and getting the number of columns/rows from a 2D array on stack overflow.
PS. This assumes you're using System.Linq

Find the index in an array of lists

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;
}

How to set list object c#

i'm using two list as methods paremeters on a controller but right now i'm getting a problem... Per example, i have the first list with three objects and the second list with three objects too. Right know i just want to get per each object from the first list the corresponding object from the second list.. like [0]-[0];[1]-[1];[2]-[2]...
I use two foreach to iterate each list but the problem cames when after i go to the second object from Turno list because after that when i start the iteration of DocenteId List the iteration starts at the [0] object but in the reality i don't want the first object of DocenteId list again but the second...
The if clause that i have is just because i cannot repeat the TurnoId value that cames with the Turno list object... The real thing happens when the DocenteId list cames with same values like object[0]-1;object[1]-1;object[1]-2; I want this to happen but i just want to get three values as result on the turnodocente List so here is the problem i just can switch the Turno object but not the DocenteId object... What happens with my method right now is that the result came with three values but foreach Turno object i get always the first object value for DocenteId list and i don't want that....
Exists some way to get this?
I will apreciate your help...
Controller method
foreach (var item in Turno)
{
foreach (var ite in DocenteId)
{
if (!turnodocente.Any(x =>x.TurnoId == item.TurnoId))
{
turnodocente.Add(new TurnoDocente
{
TurnoId = item.TurnoId,
DocenteId = ite
});
}
}
}
I don't know if i fully understand your problem but, if both lists have the same number of objects, i think the solution could be like:
for(int i=0; i<Turno.Count(); i++)
{
turnodocente.Add(new TurnoDocente
{
TurnoId = Turno[i],
DocenteId = DocenteId[i]
});
}
Let me know if it helps you.
EDIT: I just tought it might be good to explain. When you use foreach in another foreach, the iteration of indexes looks like this:
0 - 0, 0 - 1, 0 - 2... 1 - 0, 1 - 1, 1 - 2... etc so basicaly there is a * a iterations. What you need is just one iteration through both lists, so "for" loop is a good option because you will get objects from both lists that are at the same index. I hope it's clrear :)
Considering you have the same number of objects in both lists;
var Turno = new List<int>() {1000, 2000, 3000};
var DocenteId = new List<int> {5000, 6000, 7000};
var turnodocente = new List<KeyValuePair<int, int>>();
for (int i = 0; i < Turno.Count; i++)
{
if (turnodocente.All(x => x.Key != Turno[i]))
{
turnodocente.Add(new KeyValuePair<int, int>(Turno[i], DocenteId[i]));
Console.WriteLine(turnodocente[i].Key +" " + turnodocente[i].Value);
}
}
Sounds like you might need Enumerable.Zip
List<int> turno = new List<int>() {1, 2, 3};
List<string> docenteId = new List<string> {"foo", "bar", "doe"};
IEnumerable<TurnoDocente> turnodocente = turno.Zip(docenteId, (x, y) => new TurnoDocente() {TurnoId = x, DocenteId = y} );

Get first elements of List<string[]> to a string[] using LINQ

I have a list of array of string: List<string[]> myList;
Is there any way to get an array of strings with all the elements string[0]?
Like List myList to string[] where elements are myList[string[0]]
I suppose it´s something like var result = from x in myList .Take(0) select x
And question 2)
is there any way to convert a string[] to string[1,] without a for loop?
Now I do:
for (int i = 0; i < arr.Length; i++)
range[0, i] = arr[i];
I need "this syntax" because I´m exporting columns to excel. And I need an object[,] to do a range.set_Value(Type, object[,]).
string[] result = myList.Select(arr => arr.FirstOrDefault()).ToArray();
Is that what you're looking for?
Take(n) only returns an enumerable with at most n elements, so that's obviously wrong.
From what I gather from your question, this should suffice:
string[] result = (from item in myList select item.FirstOrDefault()).ToArray());
For the first part;
var temp = myList.Select(q => q.FirstOrDefault());
For the second part;
I do not think there is a direct Linq statement to convert a single dimension array to a multi dimension one.

How many elements of array are not null?

An array is defined of assumed elements like I have array like String[] strArray = new String[50];.
Now from 50 elements only some elements are assigned and remaining are left null then I want the number of assigned elements.
Like here only 30 elements are assigned then I want that figure.
You can use Enumerable.Count:
string[] strArray = new string[50];
...
int result = strArray.Count(s => s != null);
This extension method iterates the array and counts the number of elements the specified predicate applies to.
Using LINQ you can try
int count = strArray.Count(x => x != null);
Use LINQ:
int i = (from s in strArray where !string.IsNullOrEmpty(s) select s).Count();

Categories