Unable to change foreach to LINQ syntax - c#

I am trying unsuccessfully to change the following loop to a LINQ expression:
int index = 0;
IList<IWebElement> divNota = new List<IWebElement>();
foreach (IWebElement element in tablaNotas)
{
divNota.Add(element.FindElement(By.Id("accion-1-celda-0-" + index + "-0")));
index++;
}
I tried using
IList <IWebElement> divNota = tablaNotas.Select(element => element.FindElement(By.Id("accion-1-celda-0-"+ tablaNotas.IndexOf(element) + "-0"))).ToList();
But tablaNotas.IndexOf(element)always returns -1, meaning the element was not found inside tablaNotas.
The string "accion-1-celda-0-"+ tablaNotas.IndexOf(element) + "-0" is meant to change to
"accion-1-celda-0-"+ 1 + "-0"
"accion-1-celda-0-"+ 2 + "-0"
"accion-1-celda-0-"+ 3 + "-0"
...
"accion-1-celda-0-"+ n + "-0"
In accordance to element's index
Any help is appreciated

In Linq some reserved word like Where, FirstOrDefault create a condition for your query and the Select reserved word can create your object that you want the Select method applies a method to elements. It is an elegant way to modify the elements in a collection such as an array. This method receives as a parameter an anonymous function—typically specified as a lambda expression.
Example: Let's look at a program where the Select extension method is applied to a string array. A local variable of array type is allocated and three string literals are used. We use Select on this array reference.
The basic method are here:
public static System.Collections.Generic.IEnumerable<TResult> Select<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,TResult> selector);
Now! for this issue that you searched for that you can use of this code:
var divNotaResult = list
.Select((data, index) => data.FindElement(By.Id("accion-1-celda-0-" + index + "-0")))
.ToList();
In Select method do like foreach we have tow object in function data and index.
The data have each data in loop, and the index have count of loop.

var result = tableNotas
.Select((element, index) => element.FindElement(By.Id("accion-1-celda-0-" + index + "-0")))
.ToList();

Use this:
var divNota =
tablaNotas.Select((element, index) =>
element.FindElement(By.Id($"accion-1-celda-0-{index}-0")))
.ToList();

Related

Combining contents of 2 lists in C#

I just started learning C#. I want to combine 2 lists and return the output. For example:
List 1 = Peter, Tony, Steve
List 2 = Parker, Stark, Rogers
Final List/Output:
Peter Parker
Tony Stark
Steve Rogers
Here is my codes:
using System;
using System.Collections.Generic;
using System.Linq;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
var projectTeam = "Group Avengers";
Console.WriteLine("Avengers Assemble");
string[] firstNames = {"Peter", "Tony", "Steve"};
string[] lastNames = {"Parker", "Stark", "Rogers"};
IList<string> combinedNames = new List<string>();
foreach (string firstName in firstNames)
{
foreach (string lastName in lastNames)
{
Console.WriteLine(firstName + lastName);
}
}
}
}
}
Actual Output:
Avengers Assemble
PeterParker
PeterStark
PeterRogers
TonyParker
TonyStark
TonyRogers
SteveParker
SteveStark
SteveRogers
Expected Output:
Avengers Assemble
Peter Parker
Tony Stark
Steve Rogers
You could use a for-loop and access the lists via index:
for(int i = 0; i < Math.Min(firstNames.Length, lastNames.Length); i++)
{
Console.WriteLine(firstNames[i] + lastNames[i]);
}
better would it be to store the two related information in a common class, for example Avenger with properties FirstName and LastName.
Another way to link two related lists is LINQ's Zip:
var zippedAvengers = firstNames.Zip(lastNames, (f,l) => f + " " + l);
foreach(string name in zippedAvengers)
Console.WriteLine(name);
In your code you need only one loop and it should be for, not foreach
for (var i = 0; i< firstNames.Length; i++)
{
string firstName = firstNames[i];
string lastName = lastNames[i];
Console.WriteLine(firstName + lastName);
}
You can also replace this with IEnumerable.Zip (https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.zip?view=net-6.0)
firstNames
.Zip(lastNames, (first, last) => first + last)
.ToList()
.ForEach(x=>Console.WriteLine(x));
Please note that both approaches assumes that both firstNames and lastNames has the same number of elements.
If you alter the loop:
for (int i=0; i < firstNames.Count; i++)
{
Console.WriteLine(firstNames[i] + " " + lastNames[i]);
}
It'll work.
As a side note - in newer versions on .NET you can simplify the concatenation with $"{firstNames[i]} {lastNames[i]}"
Plus, the .Zip solution (as proposed by Serg):
firstNames
.Zip(lastNames, (first, last) => first + " " + last)
.ToList()
.ForEach(x=>Console.WriteLine(x));
Would be more efficient
What you are doing is you're matching every element of the first list with every element of the second list. But what you wanna do, if I get you right, is to match the first element of the first list with the first element of the second list.
In order to do that, I won't give you the code so you can learn but I can show you where to go :
Make sure your lists are both the same size, otherwise you will get an exception trying to access an inexisting index
Use for loop instead of foreach, they are less instinctive but more useful in this situation. For each index of the two lists, make the same index of the third list (the result) correspond to the concatenation of the two, for example :
result[0] = firstList[0] + secondList[0];
(In order to have a space between the two, you must add a space between the first and the second list item)
This can be done with LINQ Zip():
var fullNames = firstNames.Zip(lastNames, (first, last) => $"{first} {last}")
Zip takes the two lists and runs through both of them simultaneously, applying the function to each pair.
You are running two for loops for no reason. Just run one single loop from i = 0 to i = 3(not included).Then you can pick the ith element from both the lists.
Example. for i = 0, firstNames[0] = "Peter" lastNames[0] = "Parker"
You can print
Console.WriteLine(firstNames[i] + " " + lastNames[i]);

Issue related to Finding an Index of Item in List<string>

I am new to Linq..
i have List<string> object in my code.. i wanted to make it comma separeted, so i written following syntax
string commaSepNames = string.Join(",",lstNames.select(s=>s+" Customer").ToList());
The above syntax will result in appends with "Customer" in the end of name
with comma separated...
but now i want to Append Number (from 1 to Number of item in List) at the end of "Customer" like following:
John Customer1,
Ghanshyam Customer2,
Ferry Customer3,
... and so on..
how can i achive it in one Syntax line ? without using "for loop" or "foreach loop" ??
Thanks....
Use the overload of Enumerable.Select that gives you the index:
var names = lstNames.Select((s, index) => string.Format("{0} Customer{1}", s, index + 1));
string commaSepNames = string.Join(",", names);
If you are not using .NET 4 you need an array:
string commaSepNames = string.Join(",", names.ToArray());

How to use "in" where clause in LINQ where the string set will be supplied by a list?

I have a need to search a data source using LINQ.
In essence, the query that I want would be something like:
select * from table where id in ("1","2","4");
The added "complexity" is that the values inside the parenthesis will be coming out of string list.
This is my code:
public void getAdUserData(List<String> _inADUserDatas)
{
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where
new string[] { (char)34 + String.Join((char)34 + "," + (char)34, _inADUserDatas) + (char)34 }.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
var test = records.ToList();
Console.WriteLine((char)34 + String.Join((char)34 + "," + (char)34, _inADUserDatas) + (char)34);
as can be seen, I use String.join to convert my list into a comma-delimited string where every string is enclosed by a double-quote.
I've also tried using the code below without any luck.
new string[] {String.Join(",", _inADUserDatas) }.Contains(_adUserDatas.fan)
I also tried manually typing some of the ID in the list into the query and I am getting records.
I believe I am doing it right but it's not returning any records. The variable test has a count of 0.
Any ideas what could be wrong? I've gotten the ideas to my code by combining several discussions here in stackoverflow particularly this link here and this other link.
Thanks a lot
Call Contains on the list itself. Query provider should handle it out of the box:
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where _inADUserDatas.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
Just use contains on your collection:
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where _inADUserDatas.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
you can use below mentioned code
var list=_adUserDataDBDataContex.ADUserDatas.Where(p=>p.Contains(_adUserDatas.fan));
What's the data type for ids?
a simple collection.Where(s=> ids.Contains(s)) will translate to "in"
I'm not sure how linq to SQL translates these sorts of queries, but you don't need to sting join with commas in EF, try it without manually trying to create a comma separated list.

sort two columns by value edited

form.myDataTable.Rows[i][2 * cs] = corr;
form.myDataTable.Rows[i][2 * cs + 1] = "p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2);
I need to sort 2*cs column by values and also corresponding names in column 2*cs+1.
I am trying like this:
var corrvalues = new Dictionary();
correlationvalues["p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2)] = corr;
sortedvalues = correlationvalues.Values.OrderByDescending;
I am not clear how to use orderbydescending, i am new to c#. Thanks for help.
OrderByDescending is a function, not a property. It has one required parameter, which is a function that takes a value in the collection (in your case, correctionvalues.Values) and returns a "key" to use for comparison purposes. If you just want to compare directly on the values themselves, you can pass in an identity lambda function (e.g. x => x).
var corrvalues = new Dictionary();
correlationvalues["p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2)] = corr;
sortedvalues = correlationvalues.Values.OrderByDescending(val => val);
If your values are more complex types (such as a Person class) and you want to sort on a particular field (such as Name), then you could pass in something like this:
sorted = personDict.Values.OrderByDescending(person => person.Name);
See http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderbydescending.aspx for more detail on OrderByDescending.
You can also learn more about lambda expressions (which is useful if you're new to C#) here: http://msdn.microsoft.com/en-us/library/bb397687.aspx

ListView column highest value

I don't need to sort listView I only need to get highest value from column, all values in that column are numbers.It would be nice if I could cast it to IEnumerable<int> somehow then I could use LINQ.
Update
My existing code: DrawArray is array with random numbers.I need to get max value of index.ToString() column without creating another list or array.
for (int i = 0; i < Rounds; i++)
{
ListViewItem lvItem = new ListViewItem(i.ToString());
lvItem.SubItems.Add(new ListViewItem.ListViewSubItem(lvItem, index.ToString()));
int[] DrawArray = Draw(DrawsPerRound, RoundSize);
lvItem.SubItems.Add(new ListViewItem.ListViewSubItem(lvItem, DrawArray.Aggregate("", (s, t) => s + ", " + t.ToString()).TrimStart(new char[] { ',' })));
lvItem.SubItems.Add(new ListViewItem.ListViewSubItem(lvItem, "No"));
lvItem.BackColor = Color.PaleVioletRed;
listView1.Items.Add(lvItem);
}
Might be missing some casts or something, and it is a bit ugly, but here's an idea:
var max = listView1.Items.Cast<ListViewItem>().Max(x => int.Parse(x.SubItems[0].Text));
This uses LINQ, so make sure you have using System.Linq; in your file and are using .NET >= 3.5.
ListView.Items is ListViewItemCollection inherit of IList, ICollection, IEnumerable
By linq, you can get what you want.
System.Nullable<int> max = (
from m in listView1.Items.Cast<ListViewItem>()
select int.ParseInt(m.SubItems[0].Text)).Max();

Categories

Resources