I have a detailcollection collection in which every detail has
code, price, name
And a string with some codes
string codes = "1,2,3";
I know I can get an array using string.Split()
string[] codesarray = codes.Split(',');
But how can I get products not in codes?
// the idea I have, but I would not like to have a loop
for (int i = 0; i < codesarray.Length; i++)
{
detailcollection.Where(x => x.ope_idsku == codesarray[i])
}
I would like something like:
detailcollection.Where(x => x.ope_idsku not in (codesarray))
Selected details collection items which ids are not in codesarray:
detailcollection.Where (x=> !codesarray.Contains(x.ope_idsku))
Related
RE: Customised Web Application for Microsoft CRM Online
I've programmed a checklistbox control in ASP.NET (C#) Web Form that displays a number of items from Microsoft CRM Online via LINQ.
List<string> selDropdown = chkMyItemsHere.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
string ListBoxValues = string.Join(", ", selDropdown);
This works perfectly and I'm able to save the string into one field (i.e. 'string value, string value').
Now, on Page_Load I need to split the values from the combined string and tick the relevant checkboxes in the checkListbox.
string[] k = i.LINQFIELD.Split(',');
for (int m = 0; m <= k.Length - 1; m++)
{
for (int x = 0; x <= chkMyItemsHere.Items.Count; x++)
{
if (chkMyItemsHere.Items[x].Value == k[m])
{
chkMyItemsHere.Items[x].Selected = true;
}
}
}
Any ideas why this wouldn't be re-populating my checkboxlist? Any help would be greatly appreciated.
In your code that works, you have this:
string.Join(", ", selDropdown);
In your code that does not, you have this:
string[] k = i.LINQFIELD.Split(',');
Do you see it?
As a solution, I propose you declare a constant variable like so:
private const string SPLIT_VARIABLE = ", ";
Now you have this:
string.Join(SPLIT_VARIABLE, selDropdown);
and
string[] k = i.LINQFIELD.Split(SPLIT_VARIABLE);
After fixing how you split your comma-delimited string -- as suggested by jp2code to make sure there aren't extraneous spaces in each array element -- you can also use LINQ to select the items in your checkboxlist based on what's in your "k" string array:
(from i in chkMyItemsHere.Items.Cast<ListItem>()
where Array.Exists<string>(k, s => { return i.Value == s; })
select i).ToList().ForEach(i => i.Selected = true);
This way, you don't have to use a nested for loop to select your list items.
I'm after some help with how to query a list and return back the index, but not using Linq. I've seen many example where Linq is used, but the software I'm writing the query into doesn't support Linq. :(
So example to get us going:
List<string> location = new List<string>();
location.add(#"C:\test\numbers\FileName_IgnoreThis_1.jpg");
location.add(#"C:\test\numbers\FileName_IgnoreThis_2.jpg");
location.add(#"C:\test\numbers\FileName_ImAfterThis_3.jpg");
location.add(#"C:\test\numbers\FileName_IgnoreThis_4.jpg");
location.add(#"C:\test\numbers\FileName_ImAfterThis_5.jpg");
So this list will be populated with probably a few hundred records, what I need to do is query the list for the text "ImAfterThis" then return the index number location for this item into a string array but without using Linq.
The desired result would be 2 and 4 being added to the string array.
I was thinking of doing a for loop through the list, but is there a better way to achieve this?
List<int> results = new List<int>();
int i = 0;
foreach (string value in location)
{
if (value.Contains("IAfterThis"))
{
results.Add(i);
Console.WriteLine("Found in Index: " + i);
}
i++;
}
Console.ReadLine();
Thanks in advance.
If you want to get just the first occurrence you could simply use the IndexOf() method.
If you want all occurrences of string "whatever" then a for loop would certainly work for you. For the sake of argument here I've capture the indexes in another list:
string MyString = "whatever";
List<int> indexes = new List();
for (int i = 0; i < location.Count; i++)
{
if (location[i] == MyString)
{
indexes.Add(i);
}
}
I am using C# windows form
I have a List of arrays from a function in a class and I called the function into the form
the function returned a List of arrays, how do i get the value of the arrays?
Here is my List of array code
public List<string[]> getAccounts()
{
List<string[]> account = new List<string[]>();
while (*condition*)
{
string[] users = new string[2];
users[0] = user["firstname"].ToString();
users[1] = user["lastname"].ToString();
account.Add(users);
}
return account;
}
and when i call the function I want to show all the firstname into a listbox as well as the last name into another listbox
for (int i = 1; i <= acc.getAccounts().Count; i++)
{
listBoxFirstname.Items.Add(*all the first name from the list*);
}
Use a lambda expression to iterate through the list and select the first name
account.ForEach(s => listBoxFirstname.Items.Add(s[0]));
Without a lambda expression:
List<string[]> accounts = acc.getAccounts()
for (int i = 1; i < accounts ; i++)
{
listBoxFirstname.Items.Add(account[i][0]);
listBoxLastname.Items.Add(account[i][1]);
}
This should do the job:
List<string> firstNames = account.Select(item => item[0]).ToList();
I think will be better to use SelectMany.
listBoxFirstname.Items.AddRange(acc.getAccounts().SelectMany(item=>item[0]))
AddRange
SelectMany
EDIT:
Sorry, i'm blind, you can do it without Select many - you can just use Select
listBoxFirstname.Items.AddRange(acc.getAccounts().Select(item=>item[0]))
Let's say I have two List<string>. These are populated from the results of reading a text file
List owner contains:
cross
jhill
bbroms
List assignee contains:
Chris Cross
Jack Hill
Bryan Broms
During the read from a SQL source (the SQL statement contains a join)... I would perform
if(sqlReader["projects.owner"] == "something in owner list" || sqlReader["assign.assignee"] == "something in assignee list")
{
// add this projects information to the primary results LIST
list_by_owner.Add(sqlReader["projects.owner"],sqlReader["projects.project_date_created"],sqlReader["projects.project_name"],sqlReader["projects.project_status"]);
// if the assignee is not null, add also to the secondary results LIST
// logic to determine if assign.assignee is null goes here
list_by_assignee.Add(sqlReader["assign.assignee"],sqlReader["projects.owner"],sqlReader["projects.project_date_created"],sqlReader["projects.project_name"],sqlReader["projects.project_status"]);
}
I do not want to end up using nested foreach.
The FOR loop would probably suffice. Someone had mentioned ZIP to me but wasn't sure if that would be a preferable route to go in my situation.
One loop to iterate through both lists (assuming both have same count):
for (int i = 0; i < alpha.Count; i++)
{
var itemAlpha = alpha[i] // <= your object of list alpha
var itemBeta = beta[i] // <= your object of list beta
//write your code here
}
From what you describe, you don't need to iterate at all.
This is what you need:
http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx
Usage:
if ((listAlpga.contains(resultA) || (listBeta.contains(resultA)) {
// do your operation
}
List Iteration will happen implicitly inside the contains method. And thats 2n comparisions, vs n*n for nested iteration.
You would be better off with sequential iteration in each list one after the other, if at all you need to go that route.
This list is maybe better represented as a List<KeyValuePair<string, string>> which would pair the two list values together in a single list.
There are several options for this. The least "painful" would be plain old for loop:
for (var index = 0; index < alpha.Count; index++)
{
var alphaItem = alpha[index];
var betaItem = beta[index];
// Do something.
}
Another interesting approach is using the indexed LINQ methods (but you need to remember they get evaluated lazily, you have to consume the resulting enumerable), for example:
alpha.Select((alphaItem, index) =>
{
var betaItem = beta[index];
// Do something
})
Or you can enumerate both collection if you use the enumerator directly:
using (var alphaEnumerator = alpha.GetEnumerator())
using (var betaEnumerator = beta.GetEnumerator())
{
while (alphaEnumerator.MoveNext() && betaEnumerator.MoveNext())
{
var alphaItem = alphaEnumerator.Current;
var betaItem = betaEnumerator.Current;
// Do something
}
}
Zip (if you need pairs) or Concat (if you need combined list) are possible options to iterate 2 lists at the same time.
I like doing something like this to enumerate over parallel lists:
int alphaCount = alpha.Count ;
int betaCount = beta.Count ;
int i = 0 ;
while ( i < alphaCount && i < betaCount )
{
var a = alpha[i] ;
bar b = beta[i] ;
// handle matched alpha/beta pairs
++i ;
}
while ( i < alphaCount )
{
var a = alpha[i] ;
// handle unmatched alphas
++i ;
}
while ( i < betaCount )
{
var b = beta[i] ;
// handle unmatched betas
++i ;
}
I am programming a program to search the name from the list and I need to find them even if the keyword is not in front of the names (that's what I mean non-prefix)
e.g. if I my list is the music instruments and I type "guit" to the search textbox.
It should find the names "Guitar, GuitarrĂ³n, Acoustic Guitar, Bass Guitar, ..."
or something like this Longdo Dictionary's search suggestion.
here is my simple and stupid algorithm (that's all I can do)
const int SEARCHROWLIMIT = 30;
private string[] DoSearch(string Input, string[] ListToSearch)
{
List<string> FoundNames = new List<string>();
int max = 0;
bool over = false;
for (int k = 0; !over; k++)
{
foreach (string item in ListToSearch)
{
max = (max > item.Length) ? max : item.Length;
if (k > item.Length) continue;
if (k >= max) { over = true; break; }
if (!Input.Equals("Search")
&& item.Substring(k, item.Length - k).StartsWith(Input, StringComparison.OrdinalIgnoreCase))
{
bool exist = false;
int i = 0;
while (!exist && i < FoundNames.Count)
{
if (item.Equals(FoundNames[i]))
{
exist = true;
break;
}
i++;
}
if (!exist && FoundNames.Count < SEARCHROWLIMIT)
FoundNames.Add(item);
else if (FoundNames.Count >= SEARCHROWLIMIT) over = true;
}
}
}
return FoundNames.ToArray();
}
I think this algorithm is too slow for a large number of names and after several trial-and-error, I decided to add SEARCHROWLIMIT to breaks the operation
And I also think there're some readymade methods that can do that.
And another problem is I need to search music instruments by a category like strings, percussions, ... and by the country of origins. So I need to search them with filter by type and country.
How can I achieve this?
Using LINQ you could write code like this:
var resultSet = products
// filter products by category
.Where(product => product.Category == "strings")
// filter products by origin
.Where(product => product.Origin == "italy")
// filter products whose name contains a word starting with "guit"
.Where(product => (" " + product.Name).Contains(" guit"))
// limit the result set to the first 30 matching products
.Take(30);
If your sets of products is reasonably small, you can use LINQ-to-Objects. Otherwise you should use a database and have a look at LINQ-to-SQL.
One word. Database!
Seriously, if you want to do all these different searches, consider placing your data into a database with a schema that simplifies the categorization issues you are having. Sql Server Express now supports full text search which would be very useful for the kind of search you are trying to perform.
There's a nice blog post here about using FTS with Linq-to-Sql.
static List<string> GetItemsWithWordsStartingWithSubstring(List<string> list, string substring)
{
var query = from str in list
from item in str.Split(' ')
where item.StartsWith(substring, StringComparison.InvariantCultureIgnoreCase)
select str;
return query.ToList();
}
I hope I have read your intiial question properly. This function will return any item from the list that contains a word starting with your substring. More punctuation could be added to the split parameters. Given a list with the following contents:
"abcdef","defabc","def abc","xyz"
A search on "abc" will find "abcdef" and "def abc", but not "defabc".