My WebAPI receives two strings, one containing the display values (names), one containing the hidden values (emails).
Before, it only received one string, over which it used a foreach, and I am unsure how to get it to work with two, how to fill "name" from "nameslist":
[System.Web.Http.HttpGet]
public AjaxAnswer BatchUserCreate(string email, string names) {
string[] emaillist = email.Split('\n');
string[] nameslist = names.Split('\n');
foreach(string email in emaillist) {
db.AddParameter("#email",email);
db.AddParameter("#name",name);
int newId = db.ExecuteScalar(userInsQuery);
}
return new AjaxAnswer(newId);
}
Zip the two lists together
var nameEmailPairs = emaillist.Zip(namelist, (email,name)=>new{email,name});
You can then foreach over that, which will have items with a name and an email.
If you have a guarantee that these lists are in same order - use plain for loop:
for(int i=0; i<emaillist.Length; i++) {
string email = emaillist[i];
string name = namelist[i];
...
Or you can use LINQ with Zip:
var records = emaillist.Zip(namelist, (email, name) => new {email, name});
foreach(var r in records) {
string email = r.email;
string name = r.name;
...
You should use a for loop instead, something like this could help:
[System.Web.Http.HttpGet]
public AjaxAnswer BatchUserCreate(string email, string names) {
string[] emaillist = email.Split('\n');
string[] nameslist = names.Split('\n');
for(int i = 0; i!=emaillist.Length; ++i) {
db.AddParameter("#email", emaillist[i]);
db.AddParameter("#name", nameslist.Length > i ? nameslist[i] : "No name");
int newId = db.ExecuteScalar(userInsQuery);
}
return new AjaxAnswer(newId);
}
If the length of both arrays (emaillist & nameslist) is equal, you should use a for loop instead of a foreach loop:
[System.Web.Http.HttpGet]
public AjaxAnswer BatchUserCreate(string email, string names) {
string[] emaillist = email.Split('\n');
string[] nameslist = names.Split('\n');
for(int i = 0; i < emaillist.Length; i++) {
db.AddParameter("#email",emaillist[i]);
db.AddParameter("#name",namelist[i]);
int newId = db.ExecuteScalar(userInsQuery);
}
return new AjaxAnswer(newId);
}
try this work around hope it will help
for(int i =0 ; i< emaillist .count; i++)
{
db.AddParameter("#email",emaillist[i]);
db.AddParameter("#name",nameslist[i]);
int newId = db.ExecuteScalar(userInsQuery);
}
Try changing foreach loop to for loop:
[System.Web.Http.HttpGet]
public AjaxAnswer BatchUserCreate(string email, string names) {
string[] emaillist = email.Split('\n');
string[] nameslist = names.Split('\n');
// You should declare "newId" somewhere here
// if you want to return it via "new AjaxAnswer(newId)"
int newId = 0;
// if emaillist and nameslist have diffrent lengths
// let's take minimal length
int n = Math.Min(nameslist.Length, emaillist.Length);
for (int i = 0; i < n; ++i) {
db.AddParameter("#email", emaillist[i]);
db.AddParameter("#name", nameslist[i]);
newId = db.ExecuteScalar(userInsQuery);
}
return new AjaxAnswer(newId);
}
Related
There is a collection of input strings and a collection of query strings. For each query string, determine how many times it occurs in the list of input strings. Return an array of the results.
Function Description
The function matchingStrings must return an array of integers representing the frequency of occurrence of each query string in strings.
matchingStrings has the following parameters:
string strings[n] - an array of strings to search
string queries[q] - an array of query strings
Returns
int[q]: an array of results for each query
Solution
List<string> strings = new List<string> { "4", "aba", "baba", "aba", "xzxb" };
List<string> queries = new List<string> { "3", "aba", "xzxb", "ab" };
List<int> outputList = Result.matchingStrings(strings, queries);
for (int i = 0; i < outputList.Count; i++)
{
Console.WriteLine(outputList[i]);
}
public class Result
{
public static List<int> matchingStrings(List<string> strings, List<string> queries)
{
int inputCount = 0;
Int32.TryParse(strings[0], out inputCount);
string[] input = strings.GetRange(1, strings.Count - 1).ToArray();
var stringsMap = new Dictionary<string, int>();
for (int i = 0; i < inputCount; i++)
{
if (stringsMap.ContainsKey(input[i]))
{
stringsMap[input[i]]++;
}
else
{
stringsMap.Add(input[i], 1);
}
}
int queryCount = 0;
Int32.TryParse(queries[0], out queryCount);
string[] queryStrings = queries.GetRange(1, queries.Count - 1).ToArray();
int[] output = new int[queryCount];
for (int i = 0; i < queryCount; i++)
{
if (stringsMap.ContainsKey(queryStrings[i]))
{
output[i] = stringsMap[queryStrings[i]];
}
}
List<int> outputList = output.ToList();
return outputList;
}
}
The code works fine for the given sample input in VS code. However, when it is inserted into the HackerRank online IDE, it returns no output. I do not understand what the problem could be.
This is my 100% solution in C#:
List<int> res = new List<int>();
int count=0;
for(int i=0; i<queries.Count; i++) {
count=0;
foreach(string s in strings) {
if(queries[i] == s) {
count++;
}
}
res.Add(count);
}
return res;
}
this is my solution in python
def matchingStrings(strings, queries):
hash_map=dict()
results=[]
for str in strings:
if str in hash_map:
hash_map[str]+=1
else:
hash_map[str]=1
for q in queries:
if q in hash_map:
results.append(hash_map[q])
else:
results.append(0)
return results
public static List<int> matchingStrings(List<string> strings, List<string> queries)
{
int count = 0;
List<int> countOfOccurences = new List<int>();
foreach(var query in queries){
count = strings.Where(x => x == query).Count();
countOfOccurences.Add(count);
}
return countOfOccurences;
}
Variable.cs
public string[] CcEmails { get; set; }
Mail.cs
EDTO.CcEmails = dr["rsh_ccmail"].ToString().Split(';');
here i got two strings eg. xxxx#gmail.com ; yyy#gmail.com
MailProcess.cs
dataRPT1=get data from sql
EDTO.CcEmails = new string[dataRPT1.Rows.Count];
for (int i = 0; i < dataRPT1.Rows.Count; i++)
{
EDTO.CcEmails[i] = dataRPT1.Rows[i]["email_addr"].ToString();
}
Here i got list of string eg.aaa#gmail.com ......
I am try to add with existing but it add only new values..Anyone could help me..
I tend to use union, although that will remove duplicate entries. But to keep all entries you can use Concat on the array.
var emailString = "me#test.com;you#test.com";
string[] emails = emailString.Split(';');
string[] emailsFromSQL = new string[3];
emailsFromSQL[0] = "everyone#test.com";
emailsFromSQL[1] = "everyone2#test.com";
emailsFromSQL[2] = "everyone2#test.com";
//No Duplicates
var combined = emails.Union(emailsFromSQL).ToArray();
//Duplicates
var allCombined = emails.Concat(emailsFromSQL).ToArray();
Thanks
I find the easiest way of doing this is to create a list, add items to the list, then use string.Join to create the new string.
var items = new List<string>();
for (int i = 0; i < dataRPT1.Rows.Count; i++)
{
items.Add(dataRPT1.Rows[i]["email_addr"].ToString());
}
EDTO.CcEmails = string.Join(";", items);
Update after changed question:
If the type of the CcEmails is an array, the last line could be:
EDTO.CcEmails = items.ToArray();
I have two values in the dictionary but when I try to get the two values outside the loop I am only getting one value. The locationdesc variable value are being overwritten. Is there a better way to create unique variables to handle this issues
There are two keys location-1 and location-2. I am trying to figure out how to get both the values outside the loop. Am I doing it wrong?
string locationDesc = "";
string locationAddress = "";
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
for (int i = 1; i <= count; i++)
{
if (dictionary.ContainsKey("location-"+i))
{
string locationData = dictionary["location-"+i];
string[] locationDataRow = locationData.Split(':');
locationDesc = locationDataRow[0];
locationAddress = locationDataRow[1];
}
}
// Only getting location-2 value outside this loop since locationDesc is not unique.
Debug.WriteLine("Location Desc from dictionary is : " + locationDesc);
Debug.WriteLine("Location Add from dictionary is : " + locationAddress);
What I would like to get here is get both the values like locationDesc1 and locationDesc2 instead of locationDesc
What I am looking for is to create locationDesc and locationAddress unique so I can access both the values outside the for loop.
More Explanation as I was not very clear:
I have a dynamic table that will be created in the front end. Every time a location is created I create a cookie. For e.g. location-1, location-2 ...location-n with the location description and location values as values in the cookie. I am trying to access these values in the backend by creating a dictionary so I can assign all the values to unique variable which will make it easier for me to pass these values to a api call. I think I am over complicating a simple issue and might be doing it wrong.
My api call will be something like this:
<field="" path="" value=locationDesc1>
<field="" path="" value=locationDesc2>
The problem with your loop is that you are relying on the position of the entry in the dictionary matching the index within your loop. Your first line of code pretty much has it though:
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
What this tells me is that you are looking for all entries in your dictionary where the key starts with "location-". So why not do that directly:
var values = dictionary.Where(d => d.Key.StartsWith("location-"));
And to do the extraction/string splitting at the same time:
var values = dictionary
.Where(d => d.Key.StartsWith("location-"))
.Select(d => d.Item.Split(':')
.Select(s => new
{
LocationDesc = s[0],
LocationAddress = s[1]
});
This will give you an IEnumerable of LocationDesc/LocationAddress pairs which you can loop over:
foreach(var pair in values)
{
Debug.WriteLine(pair.LocationDesc);
Debug.WriteLine(pair.LocationAddress);
}
Try this:
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
Dictionary<string, string> values = new Dictionary<string, string>();
for (int i = 1; i <= count; i++)
{
if (dictionary.ContainsKey("location-"+i))
{
string locationData = dictionary["location-"+i];
string[] locationDataRow = locationData.Split(':');
values.Add(locationDataRow[0],locationDataRow[1]);
}
}
foreach (var item in values)
{
Debug.WriteLine(item.Key + " : " + item.Value);
}
As you are dealing with multiple values, you should go with a container where you can store all the values.
if you are dealing with only two unique values then use below code.
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
string[] locationDesc = new string[2];
string[] locationAddress = new string[2];
for (int i = 1; i <= count; i++)
{
if (dictionary.ContainsKey("location-"+i))
{
string locationData = dictionary["location-"+i];
string[] locationDataRow = locationData.Split(':');
locationDesc[i-1] = locationDataRow[0];
locationAddress[i-1] = locationDataRow[1];
}
}
for (int i = 0; i <= locationDesc.Length-1; i++)
{
Debug.WriteLine("Location Desc from dictionary is : " + locationDesc[i]);
Debug.WriteLine("Location Add from dictionary is : " + locationAddress[i]);
}
if number of unique values is not fixed then go with ArrayList
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
ArrayList locationDesc = new ArrayList();
ArrayList locationAddress = new ArrayList();
for (int i = 1; i <= count; i++)
{
if (dictionary.ContainsKey("location-"+i))
{
string locationData = dictionary["location-"+i];
string[] locationDataRow = locationData.Split(':');
locationDesc.Add(locationDataRow[0]);
locationAddress.Add(locationDataRow[1]);
}
}
for (int i = 0; i < locationDesc.Count; i++)
{
Debug.WriteLine("Location Desc from dictionary is : " + locationDesc[i]);
Debug.WriteLine("Location Add from dictionary is : " + locationAddress[i]);
}
Simple One. If you only want to show result using Debug.WriteLine, then go with below code
int count = dictionary.Count(D => D.Key.StartsWith("location-"));
for (int i = 1; i <= count; i++)
{
if (dictionary.ContainsKey("location-"+i))
{
string locationData = dictionary["location-"+i];
string[] locationDataRow = locationData.Split(':');
Debug.WriteLine("Location Desc from dictionary is : " + locationDataRow[0]);
Debug.WriteLine("Location Add from dictionary is : " + locationDataRow[1]);
}
}
Not able to prepare Code in Visual Studio at the moment therefore there may be some syntax errors.
It is hard to judge what you are event trying to do. I would not just be dumping objects you already have into other objects for fun. If you are just trying to expose values in a loop for use with another function, you can just use LINQ to iterate over the dictionary. If you want a specific value just add a where LINQ expression. LINQ should be in any .NET framework after 3.5 I believe.
public static void ApiMock(string s)
{
Console.WriteLine($"I worked on {s}!");
}
static void Main(string[] args)
{
var d = new Dictionary<int, string> {
{ 1, "location-1" },
{ 2, "location-2" },
{ 3, "location-3" }
};
d.ToList().ForEach(x => ApiMock(x.Value));
//I just want the second one
d.Where(x => x.Value.Contains("-2")).ToList().ForEach(x => ApiMock(x.Value));
//Do you want a concatenated string
var holder = string.Empty;
d.ToList().ForEach(x => holder += x.Value + ", ");
holder = holder.Substring(0, holder.Length - 2);
Console.WriteLine(holder);
}
Dear stackoverflow members,
I have this string:
string data = "1Position1234Article4321Quantity2Position4323Article3323Quantity";
I want to search for the values where the "keyword" is Position. In this case I want to get back 1 and 2. Each value is "indexed" with its own "keyword". So the value 1 in this string has the Position seperator. The value 1234 has the Article seperator and the value 4321 has the Quantity seperator.
I need a way to search through the string and want to get all positions, articles and quantitys back. Without the keywords.
Output shout be:
string[] position = {"1", "2"};
string[] article = {"1234", "4323"};
string[] quantity = {"4321", "3323"};
Hopefully some can help me here.
Thanks!
This is q quick solution I've come up with in LinqPad:
void Main()
{
string data = "1Position1234Article4321Quantity2Position4323Article3323Quantity";
var Articles = Indices(data, "Article").Dump("Articles: ");
var Posistions = Indices(data, "Position").Dump("Positions :");
var Quantities = Indices(data, "Quantity").Dump("Quantities :");
}
// Define other methods and classes here
public List<int> Indices(string source, string keyword)
{
var results = new List<int>();
//source: http://stackoverflow.com/questions/3720012/regular-expression-to-split-string-and-number
var temp = Regex.Split(source, "(?<Alpha>[a-zA-Z]*)(?<Numeric>[0-9]*)").ToList().Where (r => !String.IsNullOrEmpty(r)).ToList();
//select the list with index only where key word matches
var indices = temp.Select ((v,i) => new {index = i, value = v})
.Where (t => t.value == keyword);
foreach (var element in indices)
{
int val;
//get previous list entry based on index and parse it
if(Int32.TryParse(temp[element.index -1], out val))
{
results.Add(val);
}
}
return results;
}
Output:
Here's a possible algorithm:
Run trough the list and take each number / keyword.
Put them in a dictionary with key "keyword", value a list with all "numbers".
Iterate the dictionary and print they key + its values.
Below snippet can use to get the output like what you expected.
string data = "1Position1234Article4321Quantity2Position4323Article3323Quantity";
StringBuilder sb = new StringBuilder();
StringBuilder sbWord = new StringBuilder();
bool isDigit = false;
bool isChar = false;
Dictionary<int, string> dic = new Dictionary<int, string>();
int index = 0;
for (int i = 0; i < data.Length; i++)
{
if (char.IsNumber(data[i]))
{
isDigit = true;
if (isChar)
{
dic.Add(index, sb.ToString() + "|" + sbWord.ToString());
index++;
isChar = false;
sb.Remove(0, sb.Length);
sbWord.Remove(0, sbWord.Length);
}
}
else
{
isDigit = false;
isChar = true;
sbWord.Append(data[i]);
}
if (isDigit)
sb.Append(data[i]);
if (i == data.Length - 1)
{
dic.Add(index, sb.ToString() + "|" + sbWord.ToString());
}
}
List<string> Position = new List<string>();
List<string> Article = new List<string>();
List<string> Quantity = new List<string>();
if (dic.Count > 0)
{
for (int i = 0; i < dic.Count; i++)
{
if (dic[i].Split('|')[1] == "Position")
Position.Add(dic[i].Split('|')[0]);
else if (dic[i].Split('|')[1] == "Article")
Article.Add(dic[i].Split('|')[0]);
else
Quantity.Add(dic[i].Split('|')[0]);
}
}
string[] Position_array = Position.ToArray();
string[] Article_array = Article.ToArray();
string[] Quantity_array = Quantity.ToArray();
Try this simple solution.
class StrSplit{
public static void main(String args[]){
int i;
String str = "1Position1234Article4321Quantity2Position4323Article3323Quantity";
String pattern= "(?<=Position)|(?<=Article)|(?<=Quantity)";
String[] parts = str.split(pattern);
List<String> Position = new ArrayList<String>();
List<String> Article = new ArrayList<String>();
List<String> Quantity = new ArrayList<String>();
for( i=0;i<parts.length;i++)
{
pattern="Position";
String[] subParts;
if(parts[i].contains(pattern))
{
subParts = parts[i].split(pattern);
Position.add(subParts[0]);
}
pattern="Article";
if(parts[i].contains(pattern))
{
subParts = parts[i].split(pattern);
Article.add(subParts[0]);
}
pattern="Quantity";
if(parts[i].contains(pattern))
{
subParts = parts[i].split(pattern);
Quantity.add(subParts[0]);
}
}
System.out.println("Position:");
for(i = 0; i < Position.size(); i++) {
System.out.println(Position.get(i));
}
System.out.println("Article:");
for(i = 0; i < Article.size(); i++) {
System.out.println(Article.get(i));
}
System.out.println("Quantity:");
for(i = 0; i < Quantity.size(); i++) {
System.out.println(Quantity.get(i));
}
}
}
Output:
Position:
1
2
Article:
1234
4323
Quantity:
4321
3323
Ex: 1,4-90, 292,123
It needs to display the whole order information of
1
4,5,6....90
292
123.
Whats the gud approach to solve this.
It is similar to tracking in UPS or fedex if multiple orders are given in search box.
I meant if in a search box I giv 1,4-90, 292,123 this string the result that needs to come back is a grid representation of all the data which is corresponding to each of the order id respectively. I want to know how to parse the string into collection and send them to the database and show the information in the grid for...
1
4,5,6....90
292
123.
as a different row...from where I can generate reports too (alternative)
Please try.
static ArrayList list;
static void Main(string[] args)
{
string str = "1,4-90,292,123";
string[] arr = str.Split(',');
list = new ArrayList();
for (int i = 0; i < arr.Length; i++)
{
string tmp = arr[i];
if (tmp.IndexOf('-') != -1)
{
Range(tmp);
}
else list.Add(int.Parse(tmp));
}
list.Sort();
object[] intResult = list.ToArray();
//print the final result
for (int i = 0; i < intResult.Length; i++)
{
Console.WriteLine(intResult[i].ToString());
}
Console.Read();
}
static void Range(string range)
{
string[] tmpArr = range.Split('-');
int stInt = int.Parse(tmpArr[0]);
int edInt = int.Parse(tmpArr[1]);
int[] intArr = new int[(edInt - stInt) + 1];
for (int i = 0; stInt <= edInt; i++)
{
list.Add(stInt++);
}
}