parse querystring in asp.net with mutiple values seperated by colon - c#

I have a strange querystring formation that I need to parse. The format is - key=N:1042,B:10,C:200 . I havent encountered this format in the past, is there an easy way to extract the values of "N" , "B" , and "C" in asp.net?
Thanks!

Just a suggestion, you can also use LINQ to get parsed/split values. Like following.
var val = Request.QueryString.Get("key"); //"N:1042,B:10,C:200"
if (val.IndexOf(",") != -1)
{
var parsedValue = (from m in val.Split(',')
where m.Split(':').Count() == 2
select new { key = m.Split(':')[0], value = m.Split(':')[1] });
}
Output

use the Split Method :
string key = "N:1042,B:10,C:200";
string[] values = key.Split(',');
for (int i = 0; i < values.Length; i++)
{
var nbc = values[i].Split(':')[1];
//Do something with your var..
}
more info here : Split method MSDN

Very simply:
var val = Request.QueryString.Get("key");
var terms = val.Split(',');
foreach (var term in terms)
{
var pair = term.Split(':');
var key = pair[0];
var v = pair[1];
}

Related

Looking for next match (integer) in list of strings

I have a problem finding the next integer match in a list of strings, there are some other aspects to consider:
single string contains non relevant trailing and leading chars
numbers are formatted "D6" example 000042
there are gaps in the numbers
the list is not sorted, but it could be if there is a fast way to ignore the leading chars
Example:
abc-000001.file
aaac-000002.file
ab-002010.file
abbc-00003.file
abbbc-00004.file
abcd-00008.file
abc-000010.file
x-902010.file
The user input is 7 => next matching string would be abcd-000008.file
My attempt is :
int userInput = 0;
int counter = 0;
string found = String.Empty;
bool run = true;
while (run)
{
for (int i = 0; i < strList.Count; i++)
{
if(strList[i].Contains((userInput + counter).ToString("D6")))
{
found = strList[i];
run = false;
break;
}
}
counter++;
}
It's bad because it's slow and it can turn into a infinite loop. But I really don't know how to do this (fast).
You can parse numbers from strings with Regex and created a sorted collection which you can search with Where clause:
var strings = new[] { "abc-000001.file", "x-000004.file"};
var regP = "\\d{6}"; // simplest option in my example, maybe something more complicated will be needed
var reg = new Regex(regP);
var collection = strings
.Select(s =>
{
var num = reg.Match(s).Captures.First().Value;
return new { num = int.Parse(num), str = s};
})
.OrderBy(arg => arg.num)
.ToList();
var userInput = 2;
var res = collection
.Where(arg => arg.num >= userInput)
.FirstOrDefault()?.str; // x-000004.file
P.S.
How 9002010, 0000010, 0002010 should be treated? Cause they have 7 characters. Is it [9002010, 10, 2010] or [900201, 1, 201]?
If you don't want regex, you can do something like that:
List<string> strings = new List<string>
{
"abc-000001.file",
"aaac-000002.file",
"ab-0002010.file",
"abbc-000003.file",
"abbbc-000004.file",
"abcd-000008.file"
};
int input = 7;
var converted = strings.Select(s => new { value = Int32.Parse(s.Split('-', '.')[1]), str = s })
.OrderBy(c => c.value);
string result = converted.FirstOrDefault(v => v.value >= input)?.str;
Console.WriteLine(result);

c# Order By on List of Objects

I have a list/collection of objects with multiple fields. One of them being filename.
I am sorting based on filename but not getting the correct results.
List:
"552939_VVIDEO9.mp4"
"552939_VVIDEO8.mp4"
"552939_VVIDEO13.mp4"
"552939_VVIDEO12.mp4"
"552939_VVIDEO7.mp4"
"552939_VVIDEO6.mp4"
"552939_VVIDEO2.mp4"
"552939_VVIDEO16.mp4"
"552939_VVIDEO10.mp4"
"552939_VVIDEO3.mp4"
"552939_VVIDEO11.mp4"
"552939_VVIDEO4.mp4"
"552939_VVIDEO1.mp4"
"552939_VVIDEO15.mp4"
"552939_VVIDEO14.mp4"
"552939_VVIDEO17.mp4"
List<WfVideo> orderVideo = ProductData.Videos.OrderBy(o => o.Filename, StringComparer.InvariantCultureIgnoreCase).ToList();
Result I am getting:
VOD1
VOD2
VVIDEO1
VVIDEO10
VVIDEO11
VVIDEO12
VVIDEO13
VVIDEO14
VVIDEO15
VVIDEO16
VVIDEO17
VVIDEO2
VVIDEO3
VVIDEO4
VVIDEO5
VVIDEO6
Is the sorting incorrect?
If you want to sort these files after the number only, you could pass a Comparer to Sort that implements the rules you want. This sorts the filenames according to their number:
List<string> files = new List<string>
{
"552939_VVIDEO9.mp4",
"552939_VVIDEO8.mp4",
"552939_VVIDEO13.mp4",
"552939_VVIDEO12.mp4",
"VOD1.mp4",
"552939_VVIDEO6.mp4",
"VOD2.mp4",
"552939_VVIDEO2.mp4",
"552939_VVIDEO16.mp4",
"552939_VVIDEO10.mp4",
"552939_VVIDEO3.mp4",
"552939_VVIDEO11.mp4",
"552939_VVIDEO4.mp4",
"552939_VVIDEO1.mp4",
"552939_VVIDEO15.mp4",
"552939_VVIDEO14.mp4",
"552939_VVIDEO17.mp4"
};
files.Sort((a, b) => {
int an = 0;
int bn = 1;
var regex = new Regex("([0-9]+).mp4", RegexOptions.IgnoreCase);
var aGroups = regex.Match(a).Groups;
var bGroups = regex.Match(b).Groups;
var aidx = aGroups.Count > 1 ? 1 : 0;
var bidx = bGroups.Count > 1 ? 1 : 0;
an = int.Parse(aGroups[aidx].Value);
bn = int.Parse(bGroups[bidx].Value);
if (an == bn)
return 0;
if (an < bn)
return -1;
return 1;
});
foreach (var file in files)
{
Console.WriteLine(file);
}
Console.ReadKey();
Output:
VOD1.mp4
552939_VVIDEO1.mp4
VOD2.mp4
552939_VVIDEO2.mp4
552939_VVIDEO3.mp4
552939_VVIDEO4.mp4
552939_VVIDEO6.mp4
552939_VVIDEO8.mp4
552939_VVIDEO9.mp4
552939_VVIDEO10.mp4
552939_VVIDEO11.mp4
552939_VVIDEO12.mp4
552939_VVIDEO13.mp4
552939_VVIDEO14.mp4
552939_VVIDEO15.mp4
552939_VVIDEO16.mp4
552939_VVIDEO17.mp4
Note some additional error checking may be needed. You can offcourse extend this Comparer function to work for whatever rules you wish.

Can I store LINQ query result in an array?

This is the code using LINQ, it stores the values into list
string StringRegex = "\"(?:[^\"\\\\]|\\\\.)*\"";
Dictionary<string, string> dictionaryofString = new Dictionary<string, string>()
{
{"String", StringRegex}
};
var matches = dictionaryofString.SelectMany(a => Regex.Matches(input,a.Value)
.Cast<Match>()
.Select(b =>
new
{
Index = b.Index,
Value = b.Value,
Token = a.Key
}))
.OrderBy(a => a.Index).ToList();
for (int i = 0; i < matches.Count; i++)
{
if (i + 1 < matches.Count)
{
int firstEndPos = (matches[i].Index + matches[i].Value.Length);
if (firstEndPos > matches[(i + 1)].Index)
{
matches.RemoveAt(i + 1);
i--;
}
}
}
foreach (var match in matches)
{
Console.WriteLine(match);
}
Can it not be stored into Array? Where I can display only item I want. Just like here the output is {Index=, Value=, Token=}
Meanwhile I want the output that be of just "Value" "Token" index not needed.
You can use ToArray instead. But List gives you the desired array functionality already, you can access an item by its index.
var exampleQuery = select c from componentsDemo;
var list = exampleQuery.ToList();
var secondElement = list[1]; // <- demo only, there could be an exception thrown, if there's less than two elements in the list
EDIT: as I can see from your comments, you need this:
foreach (var match in matches)
{
Console.WriteLine(match.Value + ", " + match.Token);
}

Find MAX Number from a String List with C#

I have a string list having characters with numbers. I just wanted to split the string to get the number and later I need to find the max number from that splitted number list.
Match String
abc
Example List Values
abc9
abc100
abc999
abc
Result
abc1000
I have tried the below code
string Result="";
var SF = (from site in db.SF where site.Code == "xyz" select site.Line2).FirstOrDefault(); // Here I ll get "abc"
int Count = (from Ps in db.Ps where Ps.No.StartsWith(SF) select Ps.No).ToList().Count;
if (Count != 0)
{
var PNo = (from Ps in db.Ps where Ps.No.StartsWith(SF) select Ps.No).ToList().LastOrDefault();
if (PNo != null)
{
int Val = Convert.ToInt32(PNo.Replace(SF, "")) + 1; // Here I need to get `abc1000` based on the above ex. list.
Res = SF + Val.ToString();
}
}
else
{
Result = SF + "1";
}
When I execute the code, It always comes with "abc10" after It reached "abc45". Any help in providing the generic logic will be appreciated.
Thanks
Try below code :
var myStrings = new List<string>();
myStrings.Add("abc9");
myStrings.Add("abc100");
myStrings.Add("abc999");
myStrings.Add("abc");
var maxNumber = "abc" + (from myString in myStrings let value = Regex.Match(myString, #"\d+").Value select Convert.ToInt32(value == string.Empty ? "0" : Regex.Match(myString, #"\d+").Value) + 1).Concat(new[] { 0 }).Max();
Use OrderByDescending() to get the biggest number and then add +1 to result
var result = (from Ps in db.Ps
where Ps.No.StartsWith(SF)
select Ps.No)
.OrderByDescending(m => m.PS.No)
.FirstOrDefault();
How about this? I tried it and it seems to do what you are describing.
public static string testString(string[] input, string startString)
{
int max = 0;
try
{
max = input.Where(s => s.StartsWith(startString) && s.Length > startString.Length)
.Max(s => int.Parse(s.Replace(startString, string.Empty)));
}
catch
{
// no worries, this means max was "abc" without a number
}
return string.Format("{0}{1}", startString, (max + 1).ToString());
}
call it with
string test = testString(new string[] { "abc1", "abc123", "abc23", "xyz23" }, "abc");
try the below mentioned code to get the Max number from your List
var max = myList.Select(v => int.Parse(v.Substring(3))).Max();

How can I split an eight character string into four variables?

I hava a string like this:
var id = "01020304";
Is there a simple way I can split this into four variables called pr, pa, fo, it Each variable needs to have the two characters of the string. Looking for an elegant solution if it exists.
You can use Substring:
pr = id.Substring(0, 2);
pa = id.Substring(2, 2);
fo = id.Substring(4, 2);
it = id.Substring(6, 2);
Since you have four distinct variables, you can't get much more elegant than using Substring:
var pr = id.Substring(0, 2);
var pa = id.Substring(2, 2);
var fo = id.Substring(4, 2);
var it = id.Substring(6);
Were you looking for an array of four 2-character substrings, you could get fancier:
var parts = new string[4];
for (int i = 0 ; i != parts.Length ; i ++) {
parts[i] = id.Substring(2*i, 2);
}
EDIT: The same can be done with a LINQ expression:
var parts = Enumerable
.Range(0, id.Length/2)
.Select(i => x.Substring(2*i, 2))
.ToArray();
Try regular expression.
var id = "01020304";
string pat = "(?:(\\d{2}))";
var result = Regex.Split(id, pat).Where(p=>p!=string.Empty);
foreach (var t in result)
{
Console.WriteLine(t);
}
If you are always going to have an input of 8 characters and always require 4 variables, you can simply split the string with the Substring(...) method:
var id = "01020304";
string pr = id.Substring(0, 2);
string pa = id.Substring(2, 2);
string fo = id.Substring(4, 2);
string it = id.Substring(6, 2);
Otherwise, you can employ a method of running through a for loop and splitting off two characters at a time.
Here is a solution with a loop, which would support strings of this format, any length:
string id = "01020304";
int length = id.Length;
int[] holder = new int[length/2];
for (int i = 0; i < length/2; i++) {
holder[i] = id.Substring(i*2, 2);
}
Here is a version using Linq.
Interestingly enough, this is not so easy to achieve with just the built-in operators. The version below just uses the Linq extension methods that come with the .NET framework:
var result = "01020304".ToCharArray().
Select((c,i) => new { idx = i % 2 == 1 ? i - 1 : i, ch = c }).
GroupBy(e => e.idx,
(k,g) => new String(g.Select(e => e.ch).ToArray()));
If you use the morelinq Extensions the query can be simplified to
var result = "01020304".ToCharArray().
Batch(2).Select(ca => new String(ca.ToArray()));

Categories

Resources