I'm banging my head against the wall to try to figure something out. I've broken down what I'm trying to figure out in the simplest explanation as I can below:
Let's say I have these two string arrays with the following data:
string[] firstName = new string[2];
string[] lastName = new string[2];
firstName[0] = "John";
firstName[1] = "Jane";
lastName[0] = "Doe";
lastName[1] = "Doe";
I then have a method that this arrays are passed into:
private void Matches(IEnumerable<string> firstNames, IEnumerable<string> lastNames)
{
}
I then have two variables:
string myFirstName = "John";
string myLastName = "Doe";
How can I use Linq in the Matches method to find a complete match on the names being passed in? (the header of the Matches method has to remain how it is, unfortunately) Based on that data, I could I find the matches? I'm going gray trying to figure this one out....lol
Zip the two together and then just do a simple Where:
var myName = myFirstName + " " + myLastName;
firstNames.zip(lastNames, (first, last) => first + " " + last)
.Where(fullName=>fullName == myName)
Related
Basically I have a text file of records in this format:
(1909, 'Ford', 'Model T'),
(1926, 'Chrysler', 'Imperial'),
(1948, 'Citroën', '2CV'),
That I want to output to a text file in the following format
new Vehicle() { Id = 1, Year = 1909, Make = "Ford", Model = "Model T" },
new Vehicle() { Id = 2, Year = 1926, Make = "Chrysler", Model = "Imperial" },
new Vehicle() { Id = 3, Year = 1948, Make = "Citroën", Model = "2CV" },
I know I need to split each line in to the relevant text sections, e.g. trying to follow something like this SO question. But have hit mental block on how to get the relevant matching string sections for Year, Make and Model.
So far I have found this, that finds everthing between the parentheses:
\(([^()]+)\)
But not sure how to then group the the values and split by the commas:
Any help greatly appreciated.
Regex to get them in groups:
\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*
Make note there is problem about Citroën => You have to enter all the special symbols not within a-z, A-Z (like ë ü ÿ etc..)
To use in code, You will get the groups 1st:
string cars = #"(1909, 'Ford', 'Model T'),"
string pattern = #"\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*";
var lResult = Regex.Match(cars, pattern);
if(lResult.Success)
foreach( var iGroup in lResult.Groups)
Console.WriteLine(iGroup);
In lResult.Groups You got the info about car, You have just output it to the file as You need.
C# 6.0:
Console.WriteLine($"new Vehicle() {{ Id = 1, Year = {lResults.Groups[1]}, Make = \"{lResults.Groups[2]}\", Model = \"{lResults.Groups[3]}\"}},");
Old syntax:
Console.WriteLine(#"new Vehicle() { Id = 1, Year = "+ lMatch.Groups[1]+", Make = "+ lMatch.Groups[2] + ", Model = "+ lMatch.Groups[3] + " },");
Once You get this automatized into for loops, You can add Id easily.
My example have in Groups[0] whole string, so this is why my indexing starting from 1 to 3.
As #Toto said, \w already includes \d, there is no need to write it then.
Why not use string.Split(',')? Would be faster than Regex and suits for you (first delete the last ',' of each line, of course.
if you are willing to use a parser framework (which is maybe a little bit of an overkill), you could use for example sprache. Example without proper error handling:
Parser<string> stringContent =
from open in Parse.Char('\'').Once()
from content in Parse.CharExcept('\'').Many().Text()
from close in Parse.Char('\'').Once()
select content;
Parser<string> numberContent = Parse.Digit.AtLeastOnce().Text();
Parser<string> element = stringContent.XOr(numberContent);
Parser<List<string>> elements =
from e in element.DelimitedBy(Parse.Char(',').Token())
select e.ToList();
Parser<List<string>> parser =
from open in Parse.Char('(').Once()
from content in elements
from close in Parse.Char(')').Once()
select content;
var input = new List<string> { "(1909, 'Ford', 'Model T')", "(1926, 'Chrysler', 'Imperial')", "(1948, 'Citroën', '2CV')" };
foreach (var line in input)
{
var parsed = parser.Parse(line);
var year = Int32.Parse(parsed[0]);
var make = parsed[1];
var model = parsed[2];
Console.WriteLine(">> " + year + " " + make + " " + model);
}
You can use this snippet based on named capture groups:
var cars = new List<string>() {
"(1909, 'Ford', 'Model T')",
"(1926, 'Chrysler', 'Imperial')",
"(1948, 'Citroën', '2CV')",
};
var regex = #"(?<Year>\d+).*?'(?<Brand>.*?)'.*?'(?<Model>.*?)'";
foreach (var car in cars)
{
var match = Regex.Match(car, regex);
if (match.Success)
{
Console.WriteLine($"{match.Groups["Brand"]} make {match.Groups["Model"]} in {match.Groups["Year"]}");
}
}
Which will print:
Ford make Model T in 1909
Chrysler make Imperial in 1926
Citroën make 2CV in 1948
What is the best way to format the below string in a way so that I can separate out and find the value of PractitionerId, PhysicianNPI, PhysicianName etc.
"PractitionerId:4343343434 , PhysicianNPI: 43434343434, PhysicianName:
John, Doe, PhysicianPhone:2222222222 , PhysicianFax:3333333333 "
So finally I want something like this:
var practitionerId = "4343343434 ";
var physNPI = "43434343434";
var phyName = "John, Doe";
I was thinking of splitting with the names and finding the values assigned to each field but I am not sure if that is the best solution to it.
You could probably generalise this with a regular expression, then use it to build a dictionary/lookup of the terms.
So:
var input= "PractitionerId:4343343434 , PhysicianNPI: 43434343434,"
+ " PhysicianName: John, Doe, PhysicianPhone:2222222222 ,"
+ " PhysicianFax:3333333333";
var pattern = #"(?<=(?<n>\w+)\:)\s*(?<v>.*?)\s*((,\s*\w+\:)|$)";
var dic = Regex
.Matches(input, pattern)
.Cast<Match>()
.ToDictionary(m => m.Groups["n"].Value,
m => m.Groups["v"].Value);
So now you can:
var practitionerId = dic["PractitionerId"];
or
var physicianName = dic["PhysicianName"];
You could get the exact information, doing something like:
var str = "PractitionerId:4343343434 , PhysicianNPI: 43434343434, PhysicianName: John, Doe, PhysicianPhone:2222222222 , PhysicianFax:3333333333 ";
var newStr = str.Split(',');
var practitionerID = newStr[0].Split(':')[1]; // "4343343434"
var physicianNPI = newStr[1].Split(':')[1].Trim(); // "43434343434"
var phyName = newStr[2].Split(':')[1].Trim() + "," + newStr[3]; // "John, Doe"
There are cleaner solutions using Regex patterns though.
Also, you need to parse the corresponding variables to the specific data type you want. Everything here is being treated as a string
Since you seperate information with ",", this should work:
string[] information = yourWholeString.Split(",");
string practitionerId = information[0];
string physNPI = information[1];
string phyName = information[2] + information[3];
I am converting a single string into a string[] but I can getting the {"Non-static method requires a target."} error message. I did a search on the web and there is many cases that people have received that error but non seem to be in line with the situation I have.
Here is the code that I receive the error at:
string[] techEmail = { db.Users.Single(u => u.NTUserName.Equals(ticket.Technician.NTUserName)).EmailAddress.ToString() };
I even tried without the .ToString() and also tried to use this method:
string[] result = " [null,null,'3',null,null,null]".Replace("[","").Replace("]","").Split(',');
Here is the second attempt using the code above:
string[] techEmail = " [" + db.Users.Single(u => u.NTUserName.Equals(ticket.Technician.NTUserName)).EmailAddress.ToString() + "]".Replace("[", "").Replace("]", "").Split(',');
but nothing worked. This seems like something that should be so simple.
You can use List and add your string to it later.
Something like that:
string email = db.Users.Single(u => u.NTUserName.Equals(ticket.Technician.NTUserName)).EmailAddress.ToString();
List<string> techEmail = new List<string>();
techEmail.Add(email);
I have this linq query I am trying to optimize. I want to replace this query with a fast constant (preferably) retrieval of the value. I thought about a twin key dictionary but I have no idea which order the fname or lname will come first. I wanted to ask here if there is a fast way to do this.
I wanted to take a list of names, search through it for fname-lname the - is the delimeter and return all that match the full name that is searched. The list of people could be moderately large.
var nameList = from p in listOfPeople
where ((p.lname+"-"+p.fname == fullName)
|| (p.fname+"-"+p.lname == fullname))
select p;
Edit: listOfPeople can be any datatype, not necessarily a list.
Here's how you can create your dictionary.
var nameLookup = new Dictionary<Tuple<string,string>, List<Person>>();
foreach(var person in listOfPeople)
{
List<Person> people = null;
var firstLast = Tuple.Create(person.fname, person.lname);
if(nameLookup.TryGetValue(firstLast, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(firstLast, new List<Person> { person });
}
// If the person's first and last name are the same we don't want to add them twice.
if(person.fname == person.lname)
{
continue;
}
var lastFirst = Tuple.Create(person.lname, person.fname);
if(nameLookup.TryGetValue(lastFirst, out people))
{
people.Add(person);
}
else
{
nameLookup.Add(lastFirst, new List<Person> { person });
}
}
Then your lookup would be
// split by the delimiter to get these if needed
var fullName = Tuple.Create(firstName, lastName);
List<Person> nameList = null;
if(!nameLookup.TryGetValue(fullName, out nameList))
{
nameList = new List<Person>();
}
It's important to keep the first and last names separate or you have to pick a delimiter that will not show up the the first or last name. Hyphen "-" could be part of a first or last name. If the delimiter is guaranteed to not be part of the first or last name you can just substitute the use of the Tuple.Create(x,y) with x + delimiter + y and change the dictionary to Dictionary<string, List<Person>>.
Additionally the reason for having a List<Person> as the value of the dictionary is to handle cases like "Gary William" and "William Gary" being two different people.
In your "P" definition, which I guess it's a "People" type, I would add a "FullName" property, which will be your comparator:
public string FullName {get {return fname + "-" + lname;}}
And modify your LINQ with:
Where string.Equals(p.FullName, fullName) .
If you REALLY want to use with ANY datatype, which would include just string or even DataTable, i really don't see any better way than the way you did...
I tested with Stopwatch and this appears to be a little more effective
var nameList = from n in(
from p in listOfPeople
select new{FullName = p.fname +"-"+ p.lname}
)
where n.FullName==fullName
select n;
well i am working with xml but it is not important now, the problem is the next
it returns me something so
<xml>blalbalblal asfjñs
fasdf
iduser=dmengelblack; name=angel; lastname=uc;
blablal
iduser=cccarlos; name=carlos; lastname=uc;
how do i get (dmengelblack, angel, uc, carlos, uc)
i want to save every row...
remember all it is inside a string how do i get "dmengelblack", "angel", "uc" save it, everyone in a variable, and save all this in a variable too.. for example
string id="dmengelblack";
string name="angel";
string lastname="uc";
all="dmengelblack angel uc"
and i need to save the other row too, and all rows it can have
what do i know?
i know before than username it is "id="
i know before name it is "name="
i know before lastname it is "lastname="
i kwnow everyone finish with ";"
Simple way in java is to read the file as a stream, iterate through that and get the substring between
iduser= and ;
and
name= and ;
and
lastname= and ;
EDIT: With this code you will get the list of all the filed you want as
OUTPUT:
[iduser=dmengelblack, iduser=cccarlos]
[name=angel, name=carlos]
[lastname=uc, lastname=uc]
So now you interate through these list, split the each entry on =, you will the value you wanted at the second index on split.
CODE:
String str = "<xml>blalbalblal asfjñs" + "fasdf"
+ "iduser=dmengelblack; name=angel; lastname=uc;"
+ "blablal"
+ "iduser=cccarlos; name=carlos; lastname=uc;";
List<String> iduser = new ArrayList<String>();
List<String> name = new ArrayList<String>();
List<String> lastname = new ArrayList<String>();
int i = 1;
while(str.indexOf("iduser=", i) > 0) {
i=str.indexOf("iduser=",i);
iduser.add(str.substring(i, str.indexOf(";", i)));
name.add(str.substring(str.indexOf("name=", i), str.indexOf(";", str.indexOf("name=", i))));
lastname.add(str.substring(str.indexOf("lastname=", i), str.indexOf(";", str.indexOf("lastname=", i))));
i=str.indexOf("lastname=",i);
}
System.out.println(iduser);
System.out.println(name);
System.out.println(lastname);
hope this helps.
I would use RegEx to extract the pattern of key values into a hast table (dictionary), then use a know key mapping to assign it to the variables you have (iteration with a switch statement or something)
In c# (and other languages, but they will have different syntax) you can split a string into an array of strings like this:
string myString = "item1;item2;item3";
string[] separateStrings = myString.Split(';');
This will give you a string array like:
string[0] = "item1";
string[1] = "item2";
string[2] = "item3";
I would also suggest you clean up you tags to only tag what you really care about.