Returning list basic c sharp - c#

I am new to programming and been tasked to grab data from an API.
The issue I have is basic C# returning the contents of brakeparts. I'm passing the part id and obtaining a list of brake parts correctly. I need to assign the partid to the list, which seems to work when adding a breakpoint, however how do I return this list? Return brake parts doesn't work. They could be potentially many parts it returns whilst looping I need it to append to the Parts list. I know its probably something quite simple but I can't get my head around returning back the whole list. I've tried brakeparts.AddRange(brakeparts); This doesn't work too.
private static List<Parts> getBrakeparts(List<int> partids)
{
var restClient = new RestClient("https://example.example.net/api");
foreach (var partid in partids)
{
var returnreq = new RestRequest($"/brakeparts/{partid}/ ", Method.GET);
var res = restClient.Execute(returnreq);
Parts brakeparts = JsonConvert.DeserializeObject<Parts>(res.Content);
brakeparts.PartID = partid;
}
return brakeparts;
}

As I understand, you're simply trying to return a list of parts which you want to fill with the Parts breakparts that you deserialized from the Json response.
Simply create a List<Parts> instance and add the breakparts to it in the loop.
It could look like the following.
private static List<Parts> getBrakeparts(List<int> partids)
{
var restClient = new RestClient("https://example.example.net/api");
List<Parts> parts = new List<Parts>();
foreach (var partid in partids)
{
var returnreq = new RestRequest($"/brakeparts/{partid}/ ", Method.GET);
var res = restClient.Execute(returnreq);
Parts brakeparts = JsonConvert.DeserializeObject<Parts>(res.Content);
brakeparts.PartID = partid;
parts.Add(brakeparts);
}
return parts;
}

Related

Couchbase Lite 2 + JsonConvert

The following code sample writes a simple object to a couchbase lite (version 2) database and reads all objects afterwards. This is what you can find in the official documentation here
This is quite a lot of manual typing since every property of every object must be transferred to the MutableObject.
class Program
{
static void Main(string[] args)
{
Couchbase.Lite.Support.NetDesktop.Activate();
const string DbName = "MyDb";
var db = new Database(DbName);
var item = new Item { Name = "test", Value = 5 };
// Serialization HERE
var doc = new MutableDocument();
doc.SetString("Name", item.Name);
doc.SetInt("Value", item.Value);
db.Save(doc);
using (var qry = QueryBuilder.Select(SelectResult.All())
.From(DataSource.Database(db)))
{
foreach (var result in qry.Execute())
{
var resultItem = new Item
{
// Deserialization HERE
Name = result[DbName].Dictionary.GetString("Name"),
Value = result[DbName].Dictionary.GetInt("Value")
};
Console.WriteLine(resultItem.Name);
}
}
Console.ReadKey();
}
class Item
{
public string Name { get; set; }
public int Value { get; set; }
}
}
From my research Couchbase lite uses JsonConvert internally, so there might be a way to simplify all that with the help of JsonConvert.
Anything like:
var json = JsonConvert.SerializeObject(item);
var doc = new MutableDocument(json); // No overload to provide raw JSON
or maybe
var data = JsonConvert.SerializeToDict(item); // JsonConvert does not provide this
var doc = new MutableDocument(data);
Is there or is this some kind of optimization and the preferred approach is by intend?
People ask about this quite often, but Couchbase Lite does not actually store JSON strings in the database. They are stored in a different format so this would not give the benefit that you think (the JSON would need to be reparsed and then broken down into the other format). I'd been pushing for a way to serialize classes directly instead of going through dictionary objects (which seems like the ultimate goal here) but our priority is on things that enterprise clients want and this doesn't seem to be one of them. Note that for it to make it in, it needs to be implemented in C# Java and Objective-C / Swift.
I don't know about JsonConvert but there seems to be a constructor that takes IDictionary<string, object> as argument. So I would try something like this (brain-compiled):
MutableDocument CreateDocument(object data)
{
if (data == null) return null;
var propertyValues = new Dictionary<string, object>();
foreach (var property in data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
propertyValues[property.Name] = property.GetValue(data);
}
return new MutableDocument(propertyValues);
}
See if this works.

Looping over JSON

I'm trying to loop over a JSON string in my Android app. This is the code I have so far, using answers I found on line.
private void updateAutoComplete() {
var testJSON = "{result:[{\"symbol\":\"FB\",\"typeDisp\":\"Equity\",\"exchDisp\":\"NASDAQ\",\"exch\":\"NAS\",\"name\":\"Facebook, Inc.\",\"type\":\"S\"},{\"symbol\":\"FB2A.DE\",\"typeDisp\":\"Equity\",\"exchDisp\":\"XETRA\",\"exch\":\"GER\",\"name\":\"Facebook, Inc.\",\"type\":\"S\"}]}";
var autoCompleteOptions = getAutoCompleteOptions (testJSON);
ArrayAdapter autoCompleteAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleDropDownItem1Line, autoCompleteOptions);
var autocompleteTextView = FindViewById<AutoCompleteTextView>(Resource.Id.AutoCompleteInput);
autocompleteTextView.Adapter = autoCompleteAdapter;
}
private String[] getAutoCompleteOptions(String json) {
var autoCompleteOptions = new String[20];
int i = 0;
dynamic dynObj = JsonConvert.DeserializeObject(json);
foreach (var data in dynObj.result) { //x
autoCompleteOptions.SetValue (data.symbol, i);
i++;
}
return autoCompleteOptions;
}
Want I want is to get the different symbols from the JSON in an array so I can use it for the autocomplete.
When I run the app (updateAutoComplete is called in the OnCreate), I get following error: 'Newtonsoft.Json.Linq.JObject' does not contain a definition for 'result' on the line marked with the x.
Anyone know what might be the problem?
Thanks in advance.
If you are trying to go the route of not serializing back into an object you can cherry pick the data out of the string that you need with a JObject.
JObject root = JObject.Parse(testJSON);
var result = (JArray)root["result"];
result.ToList().ForEach(x =>
{
var symbol = x["symbol"];
symbol.Dump();
});
//FB
//FB2A.DE

Difficult to replicate objects (Customers) on the list?

I wrote a program that does work with files like delete and update, store, and search
And all customers
But I have a problem with the method is LoadAll
Once the data are read from the file and then Deserialize the object becomes
But when I want to save the list of objects in the list are repeated.
How can I prevent the duplication in this code?
var customerStr = File.ReadAllLines (address);
The code is written in CustomerDataAccess class DataAccess Layer.
Project File
The main problem with the method LoadAll Code:
public ICollection<Customer> LoadAll()
{
var alldata = File.ReadAllLines(address);
List<Customer> lst = new List<Customer>();
foreach (var s in alldata)
{
var objCustomer = customerSerializer.Deserialize(s);
lst.Add(objCustomer);
}
return lst;
}
CustomerSerialize class defined in a Field you simply use the Deserialize method you! Each series is a series Deserialize the value added items previously got into the game! (Because there is reference Type).
If you change your code to:
public Customer Deserialize(string str)
{
**Customer customer = new Customer();**
var strCustomer = str.Split(',');
customer.Id = int.Parse(strCustomer[0]);
customer.FirstName = strCustomer[1];
customer.LastName = strCustomer[2];
customer.Age = int.Parse(strCustomer[3]);
customer.Country = strCustomer[4];
return customer;
}

Create objects within a foreach to push to an array in C#

What I am trying to achieve is to split a string into multiple adresses like "NL,VENLO,5928PN" which getLocation will return a "POINT( x y)" string value.
This works. Next I need to create a WayPointDesc object for each location. And each of these objects has to be pushed into the WayPointDesc[]. I have tried various methods but I cannot find a feasable option so far. My last resort is to hardcode a maximum amount of waypoints but I would rather avoid such a thing.
Using a list is unfortunately not an option... I think.
This is the function:
/* tour()
* Input: string route
* Output: string[] [0] DISTANCE [1] TIME [2] MAP
* Edited 21/12/12 - Davide Nguyen
*/
public string[] tour(string route)
{
// EXAMPLE INPUT FROM QUERY
route = "NL,HELMOND,5709EM+NL,BREDA,8249EN+NL,VENLO,5928PN";
string[] waypoints = route.Split('+');
// Do something completly incomprehensible
foreach (string point in waypoints)
{
xRoute.WaypointDesc wpdStart = new xRoute.WaypointDesc();
wpdStart.wrappedCoords = new xRoute.Point[] { new xRoute.Point() };
wpdStart.wrappedCoords[0].wkt = getLocation(point);
}
// Put the strange result in here somehow
xRoute.WaypointDesc[] waypointDesc = new xRoute.WaypointDesc[] { wpdStart };
// Calculate the route information
xRoute.Route route = calculateRoute(waypointDesc);
// Generate the map, travel distance and travel time using the route information
string[] result = createMap(route);
// Return the result
return result;
//WEEKEND?
}
Arrays are fixed-length, if you want to dynamically add elements, you need to use some type of linked list structure. Also, your wpdStart variable was out of scope when you were adding it originally.
List<xRoute.WaypointDesc> waypointDesc = new List<xRoute.WaypointDesc>();
// Do something completly incomprehensible
foreach (string point in waypoints)
{
xRoute.WaypointDesc wpdStart = new xRoute.WaypointDesc();
wpdStart.wrappedCoords = new xRoute.Point[] { new xRoute.Point() };
wpdStart.wrappedCoords[0].wkt = getLocation(point);
// Put the strange result in here somehow
waypointDesc.add(wpdStart);
}
If you really want the list as an array later, use: waypointDesc.ToArray()

My code is very inefficient for this simple Linq usage

I have the following method that is supposed to parse information from an XML response and return a collection of users.
I've opted into creating a Friend class and returning a List<Friend> to the calling method.
Here's what I have so far, but I noticed that the ids.ToList().Count method parses every single id element to a List, then does it again in the for conditional. It's just super ineffective.
public List<Friend> FindFriends()
{
List<Friend> friendList = new List<Friend>();
var friends = doc.Element("ipb").Element("profile").Element("friends").Elements("user");
var ids = from fr in friends
select fr.Element("id").Value;
var names = from fr in friends
select fr.Element("name").Value;
var urls = from fr in friends
select fr.Element("url").Value;
var photos = from fr in friends
select fr.Element("photo").Value;
if (ids.ToList().Count > 0)
{
for (int i = 0; i < ids.ToList().Count; i++)
{
Friend buddy = new Friend();
buddy.ID = ids.ToList()[i];
buddy.Name = names.ToList()[i];
buddy.URL = urls.ToList()[i];
buddy.Photo = photos.ToList()[i];
friendList.Add(buddy);
}
}
return friendList;
}
First question - do you have to return a List<Friend>? Can you return an IEnumerable<Friend> instead? If so, performance gets a lot better:
IEnumerable<Friend> FindFriends()
{
return doc.Descendants("user").Select(user => new Friend {
ID = user.Element("id").Value,
Name = user.Element("name").Value,
Url = user.Element("url").Value,
Photo = user.Element("photo").Value
});
}
Rather than actually creating new buckets and stuffing values into them, this creates a projection, or a new object that simply contains all of the logic for how to create the new Friend objects without actually creating them. They get created when the caller eventually starts to foreach over the IEnumerable. This is called "deferred execution".
This also makes one assumption - All the <user> nodes in your XML fragment are friends. If that isn't true, the first part of the XML selection might need to be a little more complex.
And as #anon points out, even if you do need to return a List<Friend> for some reason not obvious from the information you've provided, you can just call .ToList() at the end of the return statement. This will just execute the projection I described above straight into a new bucket, so you only ever create one.
Why do you need the separate ids/names/urls/photos variables? Combine it all. You can eliminate the ToList() call if you don't need a List.
List<Friend> friendList = (from f in doc.Element("ipb").Element("profile").Element("friends").Elements("user")
select new Friend() {
ID = f.Element("id").Value,
Name = f.Element("name").Value,
URL = f.Element("url").Value,
Photo = f.Element("photo").Value
}).ToList();
return friendList;

Categories