what is this line of code does? "description = ((string[])result[0])[2];" - c#

I have a sql database and I want to use specific column of it. Code below shows the matches at the third column I just want to know what exactly ((string[])result[0])[2] does in the code.
Note: "SingleSelectWhere" function choose those records that match the word of "bag" in the "word" column.
db.OpenDB("English.db");
ArrayList result = db.SingleSelectWhere("petdef", "*", "word", "=", "'bag'");
if(result.Count > 0)
{
description = ((string[])result[0])[2];
}
db.CloseDB();

If you don't know what code does, just try to split it into some more "readable" code. If we take this line: description = ((string[])result[0])[2]; we can do:
var result1 = result;
var result2 = result[0];
var result3 = (string[])result2;
var description = result3[2].
If you set a breakpoint to the first line, just start debugging and see what every step does / the variable contains. Just as a tip.
The answer: it takes the array/list with the name result and return the first element. Than you cast it to a string-array and finally select the thrid element (zero based index!). Hope this helps.

Related

Sort a variable based on header text

I am looking for guidence, and as I tried to convey with my title, I have an issue where I receive data that sometimes look like this for example :
entry[0] = "SHAPE", "X", "Y"
entry[1] = "Circle", "2", "3"
and sometimes may look like this:
entry[0] = "X", "Y", "SHAPE"
entry[1] = "2", "3", "Circle"
As you can see, they are ordered based on the first row values, which I will call "headerValues" below.
I am now trying to map my variables (for example "shape") so it's placed where the entry actually correlates to the shape value. I want to do this so I dont end up with a X number in my "Shape" variable due to a different input order then I planned for.
I am also well aware that I may want to remove the first row before I add them into my shapes, but that is an issue I want to try and figure out on my own in order to learn. I am only here due to the fact that I have been stuck on this problem for a while now, and therefore really appriciate any help I can get from a more seasoned programmer than me.
Below you will find the code:
var csvRows = csvData.Split(';');
var headerValues = csvRows[0].Split(',');
List<Shapes> shapes = new List<Shapes>();
if (csvRows.Count() > 0)
foreach (var row in csvRows)
{
var csvColumn = row.Split(',').Select(csvData => csvData.Replace(" ", "")).Where(csvData => !string.IsNullOrEmpty(csvData)).Distinct().ToList();
if (csvColumn.Count() == 5)
{
shapes.Add(new()
{
shape = csvColumn[0], //want to have same index palcement as where headervalue contains = "Shape"
});
}
else
{
Console.WriteLine(row + " does not have 5 inputs and cannot be added!");
}
}
Thank you in advance!
You can determine your column(s) by using linq:
var colShape = headerValues.ToList().FindIndex(e => e.Equals("SHAPE"));
and then use that to set the the property in the object:
shapes.Add(new()
{
shape = csvColumn[colShape], //want to have same index palcement as where headervalue contains = "Shape"
});
In the long run you would be better off using a csv parsing library.
Since your data is in the CSV format, you don't need to reinvent the wheel, just use a helper library like CsvHelper
using var reader = new StringReader(csvData);
using var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
var shapes = csvReader.GetRecords<Shapes>().ToList();
You may need to annotate the Shapes.shape field or property if it has different casing from the data, use the NameAttribute provided by CsvHelper

Parse string to different variables c#

I've got a string fdf=232232&lid=19974832&number=1&aa_result1_1=someId1&aa_resuuuuuult2_2=someId2&aa_resuuuult3_3=someId3
and if aa exists I need to take values and add them to dictionary like:
var dict = extendedIds.Add("result1", new Dictionary<string, int[]>()
{
{
"someId1",
new int[]{ 1 }
}, ...
});
however I am having a difficult time deciding how to parse it properly? I need to accept multiple aa values (the ones that come as resultN, someIdN and a number (which is the number after resultN_NUMBER).
I tried to use substring but that doesn't work as I dont't now the length of word result
Basically it is
var parameters = $"pam=805700&laaid=19974832&kpm=1&{HttpUtility.UrlEncode("aa_{result}_{number}={id}&aa_{result}_{number}={id}&aa_{result}_{number}={id}", Encoding.UTF8)}";
So I decode it and get string:
var decoded = input.ToString().UrlDecode();
I need to accept multiple aa values, so in this example there would be three values, two of them comes from in bertween _ one after = but I wonder how to take these values then there could be something else also split by _...
also I could var parsed = HttpUtility.ParseQueryString(decoded); parse to NameValueCollection. but I can't use parsed.GetValues("aa") because the key would be e.g. aa_result1_1 and I never know beforehand what it is
this is a query string, you can use HttpUtility.ParseQueryString to parse it
see
https://learn.microsoft.com/en-us/dotnet/api/system.web.httputility.parsequerystring?view=net-5.0
Would this set you on the right track?
var qs = "fdf=232232&lid=19974832&number=1&aa_result1_1=someId1&aa_resuuuuuult2_2=someId2&aa_resuuuult3_3=someId3";
var nvc = System.Web.HttpUtility.ParseQueryString(qs);
foreach (var key in nvc.AllKeys.Where(k => k.StartsWith("aa")))
{
var id = nvc[key];
var parts = key.Split('_');
var result = parts[1];
var number = parts[2];
Console.WriteLine($"result = '{result}', number = '{number}' => id = '{id}'");
}
Use ParseQueryString to convert your string into a NameValueCollection.
Then use each key that starts with "aa"
Get its value - this is your "id"
Split the key on the _
Ignore the first part (which would be "aa") and use the next two parts
Of course you would want to add some safety: I now assume that there always are 3 parts in that key. Plus you want to do something useful with the results.
The above code prints this
result = 'result1', number = '1' => id = 'someId1'
result = 'resuuuuuult2', number = '2' => id = 'someId2'
result = 'resuuuult3', number = '3' => id = 'someId3'

Why Datagrid in WPF can sort when all data in that column is the same?

I have a question. When I try to make a custom sorting data for my datagrid. I found a problem is: Sorting is work when all data on each cell of that column is the same.
More detail: I have a list include (id, name) id is unique, but all name = "* *". This symbol is japanese.
I had try to make a class inherit Icomparer and override Comparer() method with
CompareInfo compInfo = new CompareInfo.GetCompareInfo("ja-JP");
return compInfo.Compare(str1,str2, CompareOption.StringSort) * mode;
Mode is direction of sort
I had to try all of CompareOption. Include using Strings.StrComp() of VB but it still returns a different result when sort. My expect is when all of the value of that column is the same, index of item is my datagrid will not change.
Thanks, sorry my bad english!
The problem is that the sort order is indeterminate when the names are the same. Sort also by id when the names are equal.
CompareInfo compInfo = new CompareInfo.GetCompareInfo("ja-JP");
int result = compInfo.Compare(str1, str2, CompareOption.StringSort);
if (result == 0) { // str1 and str2 are equal.
result = compInfo.Compare(id1, id2);
}
return result * mode;
Assuming the id is a string. If the ids are int, then compare
if (result == 0) { // str1 and str2 are equal.
result = id1.CompareTo(id2);
}
Note: CompareInfo.Compare and Int32.CompareTo return -1 if the first value is smaller than the second, +1 the first is lager than the second and otherwise, when both values are equal, 0.

C# Return match found with Contains

I need to return all matches found when comparing a block of text with a list of strings.
if(myList.Any(myText.Contains))
I can verify that there is a match with the above, but I'm not sure how to go further and return the matching string. I looked into Intersect, but as far as I understood it only works on two of the same type.
Sample data:
myList[] = { "City of London", "City of Edinburgh" }; etc
myText = "I am applying for the position in the City of London";
The desired result here would be "City of London", either via setting the resulting match as a string, or returning the index of myList. Any help greatly appreciated, thanks!
This should work.
List<string> myList = new List<string>();
myList.Add("City of London");
myList.Add("City of Edinburgh");
string myText = "I am applying for the position in the City of London";
var result = myList.Where(x => myText.Contains(x)).ToList();
try this:
string result= myList.FindAll(x=> myText.IndexOf(x)>-1);
var matches = myList.Where(a => myText.IndexOf(a) > 0).ToList();

IEnumerable Where filtering occuring without actually being called

I'm using HtmlAgilityPack to parse a page of HTML and retrieve a number of option elements from a select list.
The GvsaDivisions is a method that returns raw html from the result of a POST, irreverent in the context of the question
public IEnumerable<SelectListItem> Divisions(string season, string gender, string ageGroup)
{
var document = new HtmlDocument();
var html = GvsaDivisions(season);
document.LoadHtml(html);
var options = document.DocumentNode.SelectNodes("//select//option").Select(x => new SelectListItem() { Value = x.GetAttributeValue("value", ""), Text = x.NextSibling.InnerText });
var divisions = options.Where(x => x.Text.Contains(string.Format("{0} {1}", ageGroup, gender)));
if (ageGroup == "U15/U16")
{
ageGroup = "U15/16";
}
if (ageGroup == "U17/U19")
{
ageGroup = "U17/19";
}
return divisions;
}
What I'm observing is this... once the options.Where() is executed, divisions contains a single result. After the test of ageGroup == "U15/U16" and the assignment of ageGroup = "U15/16", divisions now contains 3 results (the original 1, with the addition of 2 new matching the criteria of the new value of ageGroup
Can anybody explain this anomaly? I expected to make a call to Union the result of a new Where query to the original results, but it seems it's happening automagically. While the results are what I desire, I have no way to explain how it's happening (or the certainty that it'll continue to act this way)
LINQ queries use deferred execution, which means they are run whenever you enumerate the result.
When you change a variable that is being used in your query, you actually are changing the result of the next run of the query, which is the next time you iterate the result.
Read more about this here and here:
This is actually by-design, and in many situations it is very useful, and sometimes necessary. But if you need immediate evaluation, you can call the ToList() method at the end of your query, which materializes you query and gives you a normal List<T> object.
The divisions variable contains an unprocessed enumerator that calls the code x.Text.Contains(string.Format("{0} {1}", ageGroup, gender)) on each element in the list of nodes. Since you change ageGroup before you process that enumerator, it uses that new value instead of the old value.
For example, the following code outputs a single line with the text "pear":
List<string> strings = new List<string> { "apple", "orange", "pear", "watermelon" };
string matchString = "orange";
var queryOne = strings.Where(x => x == matchString);
matchString = "pear";
foreach (var item in queryOne)
{
Console.WriteLine(" " + item);
}
I'm thinking along the same lines as Travis, the delayed execution of linq.
I'm not sure if this will avoid the issue, but I generally put my results into an immediate collection like this. With my experience it seems once you shove the results into a real defined collection I believe it may not be delayed execution.
List<SelectListItem> options = document.DocumentNode.SelectNodes("//select//option").Select(x => new SelectListItem() { Value = x.GetAttributeValue("value", ""), Text = x.NextSibling.InnerText }).Where(x => x.Text.Contains(string.Format("{0} {1}", ageGroup, gender))).ToList<SelectListItem>();

Categories

Resources