How do I compare object variable to a string? [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am using a string that comes from a form to find a object in a db with the same name of a variable.
Let's say I want to find a bus station with name "Central" in a db full of bus stations. And if I found one, I want to get the address variable from the "Central" station into a session (for further use). The db is running fine and I can retrieve other stuff from it, but the problem is comparing the two strings.
Session["searchFor"]="Central";
Session["adress"]=null;
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
foreach (Station station in allStations)
{
if(String.Compare(Session["searchFor"].toString(), station.name) == 0)
{
Session["adress"]=station.adress;
break;
}
}
I have tried every possible compare to method I have found online, but nothing seems to be working.
My DB class looks like this:
public class Station
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string adress { get; set; }
}
The page that write it out looks like this.
From station: #Session["searchFor"] <br />
From station adress: #Session["adress"] <br />
And the result,
enter image description here
the session has not been given a value by the function. I don't know if it's the compare function that does not work, or the line that are supposed to be given the session the value. If I write
if(String.Compare(Session["searchFor"].toString(), station.name) == 0)
{
Session["adress"]="TEST";
break;
}
it does NOT says "From station adress: Test" on the website either.

There is alot of improvements you can make with this code. First off, Session["searchFor"].ToString() is really Object.toString() and it is not doing what you think it is doing, it is not converting the value for the "searchFor" key to a string.
Below is a much improved version that is just common best practices in any coding language and also a couple common patterns in C#. It includes correctly spelling variables and also upper casing Properties in C# classes and dealing with potential case sensitivity of your string comparisons.
Session["searchFor"] = "Central"; //setting Session values for testing
//Session["address"] = null; there is no need for this.
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
var searchForValue = (string) Session["searchFor"];
foreach (Station station in allStations)
{
if (searchForValue.ToLower() == station.Name.ToLower())
{
Session["address"] = station.Address;
break;
}
}
And here is a version that is very common in C# using LINQ:
//setting Session values for testing
Session["searchFor"] = "Central";
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
var searchForValue = (string) Session["searchFor"];
var station = allStations.FirstOrDefault(x => x.Name.ToLower() == searchForValue.ToLower());
if (station != null)
{
Session["address"] = station.Address;
}

Related

Which C# data structure should be used to store n number (e.g. 1million) of records [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I have a Person class and my design needs to have a capacity of up to a million persons. I need to be able to load in memory. I've tried various ways and they work ok for small sets but when the count gets anywhere close to a million it takes too much time and memory. Are there any C# data structures or strategies that are specialized for what I'm trying to do which is store N number (e.g. 1 million) of records for below Class?
Class Person
{
string Id {get;set;}
}
When you say store a million Person records my assumption is that you mean persistent storage and that you're not going to enter them by hand every time you run your app. One way to achieve this goal would be to use one of the various SQLite versions to store the records in a database format. When these records are retrieved with a query, the data can be used to populate a simple data structure like List<Person> or a more complex data structure like DataTable or ViewModel. To keep things simple, this example uses the sqlite-net-pcl NuGet package.
Here, the Person class has been modified with additional tags to let SQLite know how to configure the table:
[Table("Persons")]
class Person
{
[PrimaryKey]
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString() => $"{Id} {FirstName} {LastName}";
}
The first snippet creates a temporary database in memory and inserts three records to demo a few basics. To store it on disk, just change databasePath: ":memory:" to a writable path like {MyAppDataFolderPath}\{MyDatabaseName}.db.)
var database = new SQLiteConnection(databasePath: ":memory:");
database.CreateTable<Person>();
database.Insert(new Person { Id = "Admin.1", FirstName = "Tom", LastName = "Hanks" });
database.Insert(new Person { Id = "Admin.2", FirstName = "Tom", LastName = "Holland" });
database.Insert(new Person { Id = "Staff.1", FirstName = "Tom", LastName = "Cruise" });
Here are a few example of retrieving instances of Person from the database and putting them in a List<Person> data structure.
// How many Toms?
int count = database.ExecuteScalar<int>("SELECT COUNT(*) FROM Persons WHERE FirstName='Tom'");
Console.WriteLine($"Found {count} persons named 'Tom'");
// Match a pattern
Console.WriteLine("\nList Admin:");
List<Person> recordset =
database.Query<Person>(
"SELECT * FROM Persons WHERE Id LIKE 'Admin.%'");
foreach (Person record in recordset)
Console.WriteLine(record.ToString());
// Match multiple properties
Console.WriteLine("\nGet ID for Tom Cruise Person");
Person person =
database.Query<Person>(
"SELECT ID FROM Persons WHERE FirstName='Tom' AND LastName='Cruise'"
).First();
Console.WriteLine($"ID is {person.Id}");
As commented, your question could be answered in many different ways and this is just one approach, but it's one that I use in my own production code base which is shared between PC, iOS and Android versions.

how i can get the data that stored in list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to generate a random number from first list (list of Object) and put it in the second list to get a random connection id to make connection between the original id and the random id how I can get the item from the first list by index and of which type I have to cast it
public class OneHub :Hub
{
static List<UserId> ConnectedUser = new List<UserId>();
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
static List<ConnectionsId> Connection = new List<ConnectionsId>();
public void Connect(string id)
{
if (ConnectedUser.Count(x => x.ConnectionId == id) == 0)
{
ConnectedUser.Add(new UserId { ConnectionId = id });
if (ConnectedUser.Count != 0 || ConnectedUser.Count != 1)
{
Random r = new Random();
int x = r.Next(0,ConnectedUser.Count);
(object)ConnectedUser.item[x];
Connection.Add(new ConnectionsId {ConnectionId=id,ConnectionId2= })
}}}
First off, you're going to need to make sure that the ConnectedUser that you randomly get is not the same user you are linking to, before you add that connection, or you're going to find further issues.
For ConnectedUser, you can get the index by simply using ConnectedUser[x]. (I suggest making your lists plural so it's obvious that they're collections.)
You need to assign that connected user to a new object.
Something like
UserID linkedUser = ConnectedUser[x];
This way, you can reference linkedUser.ConnectionId in your connection addition.
Alternately, you could just use:
Connection.Add(new ConnectionsId { ConnectionId = id, ConnectionId2 = ConnectedUser[x].ConnectionId };
This random setup, though, does have a strong potential for having several people ending up not linked to anyone. Additionally, your line that states:
if (ConnectedUser.Count != 0 ...
is redundant. You just added a user to that list. It should never be of size 0.

Reading a CSV file and extracting specific data [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
So I have a .CSV file which has possibly several millions, maybe even billions lines of data. The data is in the format below:
1,,5,6,7,82,4,6
1,4,4,5,6,33,4,
2,6,3,,6,32,6,7
,,,2,5,45,,6
,4,5,6,,33,5,6
What I am trying to achieve is this: Lets assume each line of data is an "event". Lets call it that. Now lets say an user says, show me all events where the 6th value is 33. You can see above that the 6th data element is a 2 digit number and the user can say show me all events where the 6th data element is 33 and the output would be:
1,4,4,5,6,33,4,
,4,5,6,,33,5,6
Also, as you can see. The data can have blanks or holes where data is missing. I don't need help reading a .CSV file or anything. I just cant wrap my mind around how I would access the 6th data element. Also, I would prefer if this output is represented in a collection of some sort maybe. I'm new to C# so I don't have much knowledge about the inbuilt classes. Any help will be appreciated!
I suggest instead of using term "event" to call this data structure more customarily as "rows and columns" and use C# Split() function to create 2d-array (string[,] or int[,]), where each element is conveniently accessible by its row/column index, and to apply whatever business logic to those elements.
Possible implementation of the CSV file reader (by line, with each line stored in the List<string> listRows) is shown below (re: Reading CSV file and storing values into an array)
using System.IO;
static void Main(string[] args)
{
var reader = new StreamReader(File.OpenRead(#"C:\YouFile.csv"));
List<string> listRows= new List<string>();
while (!reader.EndOfStream)
{
listRows.Add(reader.ReadLine());
}
}
Then apply Split(',') function to each row (stored in listRows) to compose a 2d-array string[,] and use int.TryParse() method to convert it to type int (optional, upon necessity).
Alternatively, this could be implemented by using LINQ Library, which is not recommended because of unnecessary extension of the technology surface area, plus possible performance degradation (LINQ solution expected to be slower than suggested direct processing).
Hope this may help.
Using Linq it is pretty easy to achieve. I'm posting as sample from LinqPad and providing output. All you need to do is to replace 33 with a parameter:
void Main()
{
string csvFile = #"C:\Temp\TestData.csv";
string[] lines = File.ReadAllLines(csvFile);
var values = lines.Select(s => new { myRow = s.Split(',')});
//and here is your collection representing results
List<string[]> results = new List<string[]>();
foreach (var value in values)
{
if(value.Values.Contains("33")){
results.Add(value.myRow);
}
}
results.Dump();
}
Output:
or if you want you can have it all in one shot by doing this
string csvFile = #"C:\Temp\TestData.csv";
string[] lines = File.ReadAllLines(csvFile);
var values = lines.Select(s =>
new {Position =Array.FindIndex(s.Split(','),a=>a.Contains("33"))+1
,myRow = s.Split(',')
});
so the final product will have both - the position of your search (33) and the complete string[] of items.
Create a class EventEntity. In this class create a List<int> with a constructor that initializes the list. Here is a class example:
public class EventEntity
{
public EventEntity()
{
EventList = new List<int>();
}
public List<int> EventList { get; set; }
}
From there loop through each row of data. Example:
public class EventEntityRepo
{
public EventEntity GetEventEntityByCsvDataRow(String[] csvRow)
{
EventEntity events = new EventEntity();
foreach (String csvCell in csvRow)
{
int eventId = -1;
if(csvCell != null && csvCell != String.Empty)
{
try
{
eventId = Convert.ToInt32(csvCell.Trim());
}
catch (Exception ex)
{
//failed to parse int
}
}
events.EventList.Add(eventId); //if an empty item, insert -1
}
return events;
}
}
Then you can reference the items whenever you want.
eventEntityList = GetEventEntityByCsvDataRow(csvDataRow);
eventEntitySixthElement = eventEntityList[5];
So your questions is how to access the 6th data element. It's not too hard if you have right data structure representing your csv.
Basically this csv document in abstract term can be described as IEnumerable<IEnumerable<String>>, or, maybe, IEnumerable<IEnumerable<int?>>. Having implemented csv parsing logic, you will access the 6th elements by executin:
var csvRepresenation = ParseCsv(#"D:/file.csv");
var element = csvRepresentation.ElementAt(6);
if (element == "6")
{
// do smth
}
With this aproach you will also be able to execute Linq statements on it.
Now the question is how you will implement the ParseCsv():
public IEnumerable<IEnumerable<String>> ParseCsv(string path)
{
return File.ReadAllLines(path).Select(row => row.Split(','));
}

Is there any alternate way of avoiding the Foreach loop? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Please look into the below code
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Employee> employeeCollection = new List<Employee>();
for (int i = 1; i < 10; i++) employeeCollection.Add(new Employee {
EmployeeID = i,
EmployeeName = string.Concat("Employee", i),
Email = string.Concat("Email", i) });
//loop thru every record
foreach (Employee e in employeeCollection)
{
SendEMail(e);
}
}
private static void SendEMail(Employee employee)
{
// do something
}
}
class Employee
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string Email { get; set; }
}
}
I have to do some operation on every record of the Employee. Henceforth, I am using the foreach loop. If the number of records increases, the number of operations will equally increase. So it will be O(N).
Is there any better approach for this?
N.B.~ I am not looking for .foreach()
Don't bother about O(N). Simple algorithmic complexity is rarely a good answer regarding real-life performance. The expensive part isn't iterating over the employee list, it's sending an e-mail.
If allowed by your requirements, you could use a single e-mail with multiple recipients, for example - of course, this will only work if all the e-mails are the same. Otherwise, on some level, you just have to send n separate e-mails.
Of course, there's still a lot of ways to improve the perceived performance even then. You could queue all the e-mails at once, and show the user they're waiting in a queue, rather than blocking the UI. You could send each of the e-mails in parallel. You could send the e-mails to a different service (e.g. Microsoft Exchange) to handle the actual sending for you.
In the end, though, if you're sending 100 different e-mails, you have to send 100 e-mails. No clever algorithm will help you.
what Luaan is saying is right.
But just to simplify your code, you can send email while adding employee in employeeCollection , you need not have to loop employeeCollection again to send email.
Something like this.
for (int i = 1; i < 10; i++)
{
var emp = new Employee
{
EmployeeID = i,
EmployeeName = string.Concat("Employee", i),
Email = string.Concat("Email", i)
};
employeeCollection.Add(emp);
SendEMail(emp);
}

C# Index was out of range. Must be non-negative and less than the size of the collection [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Recently i am doing the project about developing a editor,
why C# list can allow me using ADD function, but i cant assign value by indexing
can anybody help?
List<List<String>> datalist = new List<List<String>>();
....
datalist[tag.Count-1]=datasublist;
Is a problem because you're trying to assign something that doesn't exist. A list isn't like an array, where you declare it of a specific size and can use any part of what you made. Since you've declared datalist as a new List with nothing in it, there isn't anything in it you can change. You need to use
datalist.Add(datasublist);
An unrelated aside, as I noted in the comments, you can replace
line.Substring(26, EndOfIndex)
With
line.Substring(26)
It will by default return the rest of the string. Will also let you remove the EndOfIndex variable.
I'm assuming error is on the line:
datalist[tag.Count-1]=datasublist;
At first glance it seemed to me like you want a Dictionary<int, List<string>> or better yet maybe a Dictionary<string, List<string>>. In which case you can either store the value tag.Count - 1, or even the value of the tag just added. But on second thought the line above is being repeated in a loop, and it looks like you're just trying to add a bunch of strings to a correlated list.
So, I recommend using a class to store tag names and their associated data together:
class TagInfo
{
public string TagName {get; set;}
private readonly List<string> data = new List<string>();
public List<string> Data {get {return data;}}
}
Which will then allow you to do:
List<TagInfo> tags = new List<TagInfo>();
while (line != null)
{
if (line.Substring(0, 26) == "CRDI-CONTROL %%LINES-BEGIN")
{
string tagName = line.Substring(26);
TagInfo tag = new TagInfo {TagName = tagName};
tags.Add(tag);
line = reader.ReadLine();
while (line.Substring(0, 24) != "CRDI-CONTROL %%LINES-END")
{
tag.Data.Add(line.Replace(" ", String.Empty));
line = reader.ReadLine();
}
}
You could be more advanced and use a Dictionary<string, TagInfo> if you need to be looking up tags by name later. Just store the tag name as the key. You could probably clean the code up more by adding a constructor that takes a tag name, or even creating your own TagInfoCollection if you desired.

Categories