Except in LINQ C# - c#

I have to lists. One that contains all the valid chapter codes(chpt_cd) and their associated appl src codes. i.e the list is
List<ChapterCodeValidationOutput>
The base model class is
public class ChapterCodeValidationOutput
{
public string chpt_cd { get; set; }
public string appl_src_cd { get; set; }
}
The list sample data is ..
chpt_cd aapl_src_cd
------- -----------
07038 C062
07038 C062
06206 C191
And another list contains invalid chapter codes only.
List<string>
only.
And it's sample data is '06206'
I have to find the associated appl_src_cd of the invalid chapter codes list i.e. 'C191' and so on . The returned should be a list only.

Except will not help you in this case.
Assuming that these are the lists:
List<ChapterCodeValidationOutput> list1 = ...
List<string> list2 = ...
Then you can create a lookup from the first list for fast lookup like this:
var lookup = list1.ToLookup(x => x.chpt_cd, x => x.appl_src_cd);
And then use it like this to get the list of corresponding codes:
var result = list2.Select(x => lookup[x].First()).ToList();
I am assuming (since you mentioned in the comments), that if there are duplicate chpt_cd values, the corresponding appl_src_cd values will be equal.

Related

Indexes that correspond to each other in two Lists

I have two Lists:
List<string> names = new List<string>();
List<int> goals = new List<int>();
One of them is a string List while the other one is a int List. I add some numbers in the second List, and then I get the biggest number in the List. This works.
Now I need to type some names in the console and after each name I need to type a certain number and this repeats to whenever I want.
How do I get the index of the biggest number in the second list and to print it alongside the name that actually have "scored" that biggest number? I want to get the index from the first string List that corresponds to the index of the biggest number in the second List. Is there a way that I can do it?
In your case, "Name" and "Goals" relate to each other. Someone or something with a "Name" has obviously attached to them a number of "Goals". So, let's reflect this relation in a class:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
}
You then can create new instances of that class like so:
var item = new StatisticsItem() { Name = "Marc", Goals = 5 };
and you can put those in a list:
var myList = new List<StatisticsItem>();
myList.Add(item);
Find your champion:
using System.Linq;
// ...
Console.WriteLine("Goalie King: {0}", myList.MaxBy(x => x.Goals).Name);
See in action: https://dotnetfiddle.net/I9w5u7
To be a bit more clean, you could of course use a constructor:
public class StatisticsItem
{
// Properties here
public string Name {get; set;}
public int Goals {get; set;}
public StatisticsItem(string name, int goals)
{
Name = name;
Goals = goals
}
}
// and then create instances like so:
var item = new StatisticsItem("Marc", 5);
Can't comment so i will add my opinion here. Fildor suggested 1 list with 2 properties which should cover your case. I would say also check if a dictionary<string, int> or a dictionary<string, List<int>> is a better fit instead of a list.
Keep in mind for a dictionary to work the key (name in your case) must be unique. If not discard this answer

Dynamically build a int[] array from the database

I'm trying to build a int[] array from returned values from the database,
Normally for an int[] array that isn't database driven you would do something like this:
int[] arr1 = new int[] { 3, 4, 5 };
my public variable is as follows:
public int[] SelectedItems { get; set; } // Which is used for the multi select list box
I then when retrieving the values do something like this:
model.SelectedItems = (from x in collection select x.Id).ToArray();
but I get the error:
Cannot convert source type 'dynamic[]' to target type 'int[]'
I have googled this error but with no avail.
My collection looks like this:
public class UserActivities
{
public int Id { get; set; }
public string ActivityDesc { get; set; }
}
Update
I'm using dapper.net to retrieve the values so once I've made the call to the DB I then read it as follows:
var activities = sqlCon.Read().ToList();
I use this in two places, first place I display the string description which is shown on the page for the user, the Id's I try to reference and build an array which is used else where in the application.
Your (from x in collection select x.Id) requires an IEnumerable<UserActivities> or IQueryable<UserActivities> as the type for the collection variable. The error you are getting is because collection seems to be an IEnumerable<dynamic>.
Given that you mentioned in your edit and the comments that you are using Dapper.NET and the query is performed using the QueryMultiple method, you will need to get the result set with elements of type UserActivities.
This can be achieved using
var collection = sqlCon.Read<UserActivities>().ToList();
which will extract that result set from the multiple query result.

Convert List to List<string>

I have the following problem:
public class AwesomeClass
{
public string SomethingCool { get; set; }
public string SomethingUseless { get; set; }
}
I have a class which contains a number of properties, and I need to convert a list of these classes into a list of strings, where the string represents a property in the class.
List<AwesomeClass> stuff = new List<AwesomeClass>();
//Fill the stuff list with some tings.
List<string> theCoolStuff = //Get only the SomethingCool property in the AwesomeClass list.
The reason why I need to convert this to a list of strings is because I have a method which takes a List as a parameter, but the SomethingCool property contains the data that I need for this list.
Note: I could use a foreach loop on the list and populate the List of strings but I'm looking for a more elegant method, perhaps LINQ can do this for me?
You can simply use Select:
var theCoolStuff = stuff.Select(x => x.SomethingCool).ToList();
What Select does is a projection, it projects each item and transforms (not convert) them into another form.
Note that you can even:
List<string> theCoolStuff = stuff.ConvertAll(x => x.SomethingCool);
because the List<T> has a special "conversion" method :-)
foreach (AwesomeClass member in stuff)
{
theCoolStuff.Add(member. SomethingCool)
}

Sort the List based on number of times a word appear in the string

I have got a List which is
IEnumerable<RSPCA.LIB.Models.Search.SearchItem> results =
newList<LIB.Models.Search.SearchItem>();
My searchItem class has got a string field named content. So basically I want to sort list based on the number of time a specific string(term) appears in the content string.
So lets say my term is "abc", so if one item in the list's content field contain "abc" twice and other one contains "abc" 3 times than I want this one to be before the one which contains it twice. So basically sorting the list based on Occurrence. I have also pasted my search item class here:
public class SearchItem : SearchResultItem
{
public string PageTitle { get; set; }
public string PageDescription { get; set; }
public string content {get; set;} // That's the one which I want to use
}
Any help is highly appreciated
Try this:-
var result = items.OrderByDescending(x => Regex.Matches(x.content,"abc").Count);
Working Fiddle.
You can do this using the following code and NinjaNye.SearchExtensions nuget package
var results = items.Search(x => s.content)
.Containing("abc")
.ToRanked()
.OrderByDescending(x => x.Hits)
.Select(x => x.Item);
This should be considerably faster than the regex implementation should that be of importance in your implementation

Select section of list based on value of a enumeration

I have a c# app. I have custom list of type result, shown below. The list is called 'myResultList'.
enumResult { noResult = 0, win = 1, lose = 2 }
class Result
{
public enumResult OutCome {get; set;}
public double Frequency {get;set;}
public string GroupName {get; set;}
public double TotalValue {get; set;}
}
myResultList contains numerous elements. I wish to select all the elements where the Outcome equals lose into a new list. I believe LINQ is probably best for this task, correct me if I am wrong. How do I go about querying a list based on a enumeration?
var lostResults = myResultList.Where(r => r.OutCome == enumResult.lose).ToList();
NOTE: Consider to have Pascal Case names for types and public members. And don't include prefixes in type names. E.g.
public enum Outcome
{
NoResult,
Win,
Lose
}
If you will need to filter results by other types of outcomes, then consider to use lookup:
var results = myResultList.ToLookup(r => r.OutCome);
Then getting results by their type will be easy:
var wonResults = results[enumResult.won];
var newList = myResultList.Where(r => r.OutCome == enumResult.lose).ToList();

Categories