I am trying to make retrieve a certain string from a list of object in c#( let's call that list userlist)(the list has about 1600 elements in it and each object has about 15 different parameters).
So this is the code that I have:
private List<String> getGameList(CommandEventArgs e) {
List<String> allgames = new List<string>();
List<User> userlist = e.Server.Users.ToList();
foreach (User u in userlist)
{
if (u.CurrentGame.ToString() != "")
{
if (u.CurrentGame.Value.Name != null)
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
But it everytime that this bit of code runs the list that gets returned has only one or two results in it while it should retrieve a lot more.
To give more information about the code:
User is the object with about 15 parameters/objects under it
u.CurrentGame retrieves an object called "Game" that is under a "User"
u.CurrentGame.Value.Name is the string that I want to retrieve and add in the new "allgames" list
I know the Insert(0,String) is strange but for some reason a simple .Add didn't seem to work properly either
Any idea why I only have 1 or 2 results and not more while it should?
I can definitly provide more information if needed.
Thank you
Without seeing the complete code my guess is that you either have an early return or a break somewhere in your loop where you probably should have been using a continue instead to continue iterating through the list.
You should also probably be using string.IsNullOrEmpty(s) instead of the comparison with "".
That's all the help I can give with the information you've provided.
I did small experiment 3 cases, and all 3 cases works somehow:
using System;
using System.Collections.Generic;
using System.Linq;
namespace p44785433
{
class Program
{
static List<User> userList = UserFactory.GenerateUsers();
static void Main(string[] args)
{
Console.WriteLine("Number Of Users: {0}", userList.Count);
var x = getGameList(userList); // 1600 on output
var y = getGameListUpdated(userList); // 1600< on output depend of randomized empty name
var z = getGameListLinq(userList); // 1600< on output depend of randomized empty name
}
private static List<String> getGameList(List<User> parUserList)
{
List<string> allgames = new List<string>();
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
foreach (User u in userlist)
{
if (u.CurrentGame.ToString() != "")
{
if (u.CurrentGame.Value.Name != null)
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
private static List<String> getGameListUpdated(List<User> parUserList)
{
List<string> allgames = new List<string>();
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
foreach (User u in userlist)
{
if (!string.IsNullOrEmpty(u.CurrentGame.ToString()))
{
if (!string.IsNullOrEmpty(u.CurrentGame.Value.Name))
{
allgames.Insert(0, u.CurrentGame.Value.Name);
}
}
}
return allgames;
}
private static List<String> getGameListLinq(List<User> parUserList)
{
List<User> userlist = /*e.Server.Users.ToList();*/ parUserList;
var x = userList.Where(r => !string.IsNullOrEmpty(r.CurrentGame.ToString()) && !string.IsNullOrEmpty(r.CurrentGame.Value.Name)); // remove empty
var y = x.Select(r => r.CurrentGame.Value.Name); // select strings
var z = y.Reverse(); // reverse order instead of insert
return z.ToList();
}
}
internal class User
{
public Game CurrentGame { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
internal static User CreateDummy()
{
return new User()
{
CurrentGame = Game.CreateDummy(),
Par6 = UserFactory.Rnd.NextDouble().ToString(),
Par12 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
internal static class UserFactory
{
static Random _rnd;
internal static Random Rnd
{
get
{
if (_rnd == null) _rnd = new Random();
return _rnd;
}
}
internal static List<User> GenerateUsers()
{
List<User> list = new List<User>();
for (int i = 0; i < (int)1600; i++)
{
list.Add(User.CreateDummy());
}
return list;
}
}
internal class Game
{
public Value Value { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
public override string ToString()
{
return Par6;
}
internal static Game CreateDummy()
{
return new Game()
{
Value = Value.CreateDummy(),
Par6 = UserFactory.Rnd.NextDouble().ToString(),
Par12 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
internal class Value
{
public string Name { get; set; }
public string Par1 { get; set; }
public string Par2 { get; set; }
public string Par3 { get; set; }
public string Par4 { get; set; }
public string Par5 { get; set; }
public string Par6 { get; set; }
public string Par7 { get; set; }
public string Par8 { get; set; }
public string Par9 { get; set; }
public string Par10 { get; set; }
public string Par11 { get; set; }
public string Par12 { get; set; }
public string Par13 { get; set; }
public string Par14 { get; set; }
internal static Value CreateDummy()
{
return new Value()
{
Name = (UserFactory.Rnd.Next(10)!=0 ? string.Format("XXA{0}XAA", UserFactory.Rnd.NextDouble()): string.Empty),
Par5 = UserFactory.Rnd.NextDouble().ToString(),
Par11 = UserFactory.Rnd.NextDouble().ToString()
};
}
}
}
Related
I have two lists and I want to compare these and update below fields using 2nd list value StudentAddressLine1,StudentAddressLine2,StudentAddressPincode,StudentAddressCity,StudentAddressState
Student Class
public class Student
{
public string StudentNumber { get; set; }
public string StudentName { get; set; }
public string StudentClass { get; set; }
public string StudentPhoneNumber { get; set; }
public string StudentEmail { get; set; }
public string StudentFatherPhoneNumber { get; set; }
public string StudentFatherEmail { get; set; }
public string StudentMotherPhoneNumber { get; set; }
public string StudentMotherEmail { get; set; }
public string StudentAddressLine1 { get; set; }
public string StudentAddressLine2 { get; set; }
public string StudentAddressPincode { get; set; }
public string StudentAddressCity { get; set; }
public string StudentAddressState { get; set; }
}
AddressFromExternalAPI Class
public class AddressFromExternalAPI
{
public string SNumber { get; set; }
public string SName { get; set; }
public string SClass { get; set; }
public int ID { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine1 { get; set; }
public string Pincode { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Below is my code where I use a loop and compare two lists and update the fields
public virtual IEnumerable<Student> getStudentDetails(IEnumerable<Student> students)
{
var studentList = new List<Student>();
var addresslist = getStudentAddress(students)
studens.ForEach((y, index ) =>
{
foreach (var address in addresslist)
{
studentHelper.addAddress(y, ds);
studentList.Add(y);
}
});
return studentList;
}
public static void addAddress(Student student, AddressFromExternalAPI address)
{
student.StudentAddressLine1 = address.AddressLine1;
student.StudentAddressLine2 = description.AddressLine2;
student.StudentAddressPincode = description.Pincode;
student.StudentAddressCity = description.City;
student.StudentAddressState = description.State;
}
could you please advise some other way to implement this logic instead of foreach?
Is there any other way instead of doing multiple loops?looking for a more compact solution?
Ignoring ID, and assuming matching based on Number, Name and Class is sufficient, you can store the addresses in a Dictionary and lookup the matches:
public virtual IEnumerable<Student> getStudentDetails(IEnumerable<Student> students) {
var addressDict = getStudentAddress(students).ToDictionary(a => (a.SNumber, a.SName, a.SClass));
var studentList = students.ToList();
foreach (var student in studentList) {
if (addressDict.TryGetValue((student.StudentNumber, student.StudentName, student.StudentClass), out var address)) {
student.StudentAddressLine1 = address.AddressLine1;
student.StudentAddressLine2 = address.AddressLine2;
student.StudentAddressPincode = address.Pincode;
student.StudentAddressCity = address.City;
student.StudentAddressState = address.State;
}
}
return studentList;
}
I tried to make it as much as possible with the information given. List<T>.ForEach(Action<T>) cannot get index.
public static IEnumerable<Student> getStudentDetails(IEnumerable<Student> students)
{
var addressList = getStudentAddress(students);
var result = students
.Select((student, index) => (student, index))
.SelectMany(pair => addressList,
(pair, address) => (pair, address))
.Where(p =>
p.pair.index + 1 == p.address.ID &&
p.pair.student.StudentNumber == p.address.SNumber &&
p.pair.student.StudentName == p.address.SName &&
p.pair.student.StudentClass == p.address.SClass)
.Select(p => (p.pair.student, p.address));
var studentList = new List<Student>();
foreach (var (student, address) in result)
{
addAddress(student, address);
studentList.Add(student);
}
return studentList;
}
I have an Api in .net with EF, and the frontEnd needs to get the json in a particular way.
Originally i tried with this code:
[HttpGet("getTrafos")]
public IEnumerable<object> GetTrafos(){
var resultado =_context.Transformadores.OrderBy(z=>z.Anio).ThenBy(z=>z.Mes).ThenBy(x=>x.Prioridad)
.Include(t => t.Etapa).ThenInclude(x=>x.IdColorNavigation)
.Include(f=>f.Etapa).ThenInclude(x=>x.EtapaEmpleado)
.ToList();
List<Object> array = new List<Object>();
foreach(var result in resultado){
result.Etapa=result.Etapa.OrderBy(m=>m.IdTipoEtapa).ToList();
var mes = AsignarMes(resultado[0].Mes);
var obj=new {group = $"{mes} de {resultado[0].Anio}"};
var ultimoAnio=resultado[0].Anio;
var ultimoMes=mes;
array.Add(obj);
foreach(var trafo in resultado)
{
mes=this.AsignarMes(trafo.Mes);
if(trafo.Anio!=ultimoAnio)
{
obj=new {group = $"{mes} de {resultado[0].Anio}"};
array.Add(obj);
array.Add(trafo);
}
else{
if(mes!=ultimoMes)
{
obj=new{group=$"{mes} de {trafo.Anio}"};
array.Add(obj);
}
array.Add(trafo);
}
ultimoAnio=trafo.Anio;
ultimoMes=mes;
}
}
return array;
}
AsignarMes Method:
private string AsignarMes(int? mes){
var map = new Dictionary<int, string>()
{
{1, "Enero"},
{2, "Febrero"},
{3, "Marzo"},
{4,"Abril"},
{5,"Mayo"},
{6,"Junio"},
{7,"Julio"},
{8,"Agosto"},
{9,"Septiembre"},
{10,"Octubre"},
{11,"Noviembre"},
{12,"Diciembre"}
};
string output;
return map.TryGetValue(mes.GetValueOrDefault(), out output) ? output : "";
}
but for performance reasons (it takes 13 seconds aprox to download the content to the frontend) i tried with another way:
var resultado =_context.Transformadores.OrderBy(z=>z.Anio).ThenBy(z=>z.Mes).ThenBy(x=>x.Prioridad)
.GroupBy(x=> new { x.Anio, x.Mes }, (key, group) => new
{
Anio = key.Anio,
Mes = key.Mes,
Trafos = group.ToList()
});
List<Object> array = new List<Object>();
foreach (var result in resultado) {
foreach (var trafo in result.Trafos)
{
trafo.Etapa = trafo.Etapa.OrderBy(m => m.IdTipoEtapa).ToList();
}
var mesEnLetras = this.AsignarMes(result.Mes);
var obj = new {group = $"{mesEnLetras} de {result.Anio}"};
array.Add(obj);
array.AddRange(result.Trafos);
}
return array;
The performance was better with this last code but the problem is that i canĀ“t Include Etapa, IdColorNavigation and EtapaEmpleado.
Is there another way to do this?
Theese are the Models:
using System;
using System.Collections.Generic;
namespace Foha.Models
{
public partial class Transformadores
{
public Transformadores()
{
Etapa = new HashSet<Etapa>();
}
public int IdTransfo { get; set; }
public string OPe { get; set; }
public int? OTe { get; set; }
public string Observaciones { get; set; }
public int RangoInicio { get; set; }
public int RangoFin { get; set; }
public int? IdCliente { get; set; }
public string NombreCli { get; set; }
public int Potencia { get; set; }
public int? IdTipoTransfo { get; set; }
public DateTime? FechaCreacion { get; set; }
public int? Mes { get; set; }
public int? Anio { get; set; }
public int? Prioridad { get; set; }
public virtual Cliente IdClienteNavigation { get; set; }
public virtual TipoTransfo IdTipoTransfoNavigation { get; set; }
public virtual ICollection<Etapa> Etapa { get; set; }
}
}
using System;
using System.Collections.Generic;
namespace Foha.Models
{
public partial class Etapa
{
public Etapa()
{
EtapaEmpleado = new HashSet<EtapaEmpleado>();
}
public int IdEtapa { get; set; }
public int? IdTipoEtapa { get; set; }
public DateTime? DateIni { get; set; }
public DateTime? DateFin { get; set; }
public bool? IsEnded { get; set; }
public string TiempoParc { get; set; }
public string TiempoFin { get; set; }
public int? IdTransfo { get; set; }
public string IdEmpleado { get; set; }
public string Hora { get; set; }
public DateTime? InicioProceso { get; set; }
public int? IdColor { get; set; }
public int? NumEtapa { get; set; }
public virtual Colores IdColorNavigation { get; set; }
public virtual TipoEtapa IdTipoEtapaNavigation { get; set; }
public virtual Transformadores IdTransfoNavigation { get; set; }
public virtual ICollection<EtapaEmpleado> EtapaEmpleado { get; set; }
}
}
I am using a stored procedure to return data to my datagrid view, but clicking the header does nothing when I want it to sort.
I used a tutorial to get this far so I dont really understand whats going on.
I have used google to try and find the problem but it talks about list and binding lists but i just dont understand it.
Can anyone see the problem below?
public Form_ManagerChanges()
{
InitializeComponent();
UpdateBinding();
}
private void UpdateBinding()
{
OccupanciesFoundDataGrid.DataSource = Occupancies;
OccupanciesFoundDataGrid.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.DisplayedCells;
}
public class DataAccess
{
public List<Occupancies> GetOccupancies (string searchText, string searchType)
{
using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(Helper.CnnVal("HRIS_DB")))
{
if (searchType == "Personal Reference")
{
var output = connection.Query<Occupancies>("hris.spManagerChangeTool_GetByPersonalRef #PersonalRef", new { PersonalRef = searchText }).ToList();
return output;
}
else if (searchType == "Forename")
{
var output = connection.Query<Occupancies>("hris.spManagerChangeTool_GetByForename #Forname", new { Forname = searchText }).ToList();
return output;
}
else if (searchType == "Surname")
{
var output = connection.Query<Occupancies>("hris.spManagerChangeTool_GetBySurname #Surname", new { Surname = searchText }).ToList();
return output;
}
else if (searchType == "Reporting Unit")
{
var output = connection.Query<Occupancies>("hris.spManagerChangeTool_GetByReportingUnit #ReportingUnit", new { ReportingUnit = searchText }).ToList();
return output;
}
else
{
var output = connection.Query<Occupancies>("hris.spManagerChangeTool_GetByMgrPersonalRef #MgrPersonalRef", new { MgrPersonalRef = searchText }).ToList();
return output;
}
}
}
public class Occupancies
{
[DisplayName("Personal Reference")]
public string PERSONAL_REFERENCE { get; set; }
[DisplayName("Forename")]
public string FORENAME { get; set; }
[DisplayName("Surname")]
public string SURNAME { get; set; }
[DisplayName("Level 3")]
public string STRUCTURE_LVL3 { get; set; }
[DisplayName("Level 4")]
public string STRUCTURE_LVL4 { get; set; }
[DisplayName("Level 5")]
public string STRUCTURE_LVL5 { get; set; }
[DisplayName("Level 6")]
public string STRUCTURE_LVL6 { get; set; }
[DisplayName("Level 7")]
public string STRUCTURE_LVL7 { get; set; }
[DisplayName("Reporting Unit")]
public string REPORTING_UNIT { get; set; }
[DisplayName("Post Reference")]
public string POST_REFERENCE { get; set; }
[DisplayName("Post")]
public string POST { get; set; }
[DisplayName("Position Reference")]
public string POSITION_REFERENCE { get; set; }
[DisplayName("Position")]
public string POSITION_NAME { get; set; }
[DisplayName("Mgr - Personal Reference")]
public string MGR_PERSONAL_REFERENCE { get; set; }
[DisplayName("Mgr - Forename")]
public string MGR_FORENAME { get; set; }
[DisplayName("Mgr - Surname")]
public string MGR_SURNAME { get; set; }
[DisplayName("Mgr - Position Reference")]
public string MGR_POSITION_REFERENCE { get; set; }
[DisplayName("Mgr - Position")]
public string MGR_POSITION { get; set; }
}
I'm trying to deserialize a Json String to a object but I only get 0 and null back.
Here is my code:
string result = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var serializer = new DataContractJsonSerializer(typeof(LandRootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (LandRootObject)serializer.ReadObject(ms);
public class LandRootObject
{
public int page { get; set; }
public int pages { get; set; }
public string per_page { get; set; }
public int total { get; set; }
[DataMember]
public List<Land> land { get; set; }
}
Thanks!
I have tested this method and it's working.
Your entity classes. (I did not code all these classes. They are code generated using paste special.)
public class LandRootObject
{
public int page { get; set; }
public int pages { get; set; }
public string per_page { get; set; }
public int total { get; set; }
}
public class LandBodyObject
{
public string id { get; set; }
public string iso2Code { get; set; }
public string name { get; set; }
public Region region { get; set; }
public Adminregion adminregion { get; set; }
public Incomelevel incomeLevel { get; set; }
public Lendingtype lendingType { get; set; }
public string capitalCity { get; set; }
public string longitude { get; set; }
public string latitude { get; set; }
}
public class Region
{
public string id { get; set; }
public string value { get; set; }
}
public class Adminregion
{
public string id { get; set; }
public string value { get; set; }
}
public class Incomelevel
{
public string id { get; set; }
public string value { get; set; }
}
public class Lendingtype
{
public string id { get; set; }
public string value { get; set; }
}
Then the deserialisation method. Your Json has two parts. So I am splitting it in to 2 for deserialisation.
string result = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var parts = result.Split(new[] {",["}, StringSplitOptions.None);
if (parts.Length > 1)
{
var header = parts[0].Replace("[", "");
var jsonHeader = JsonConvert.DeserializeObject<LandRootObject>(header);
var body = "[" + parts[1].Replace("]]","]");
var jsonBody = JsonConvert.DeserializeObject<List<LandBodyObject>>(body);
}
Use List type
var serializer = new DataContractJsonSerializer(typeof(List<LandRootObject>));
// ...
var data = (List<LandRootObject>)serializer.ReadObject(ms);
Edit:
Now I see - your json array consists of 2 different elements. I suppose its [RootObject, Lands]. You better use the Newtonsoft.Json to deserialize the object.
var str = "[{\"page\":1,\"pages\":1,\"per_page\":\"50\",\"total\":1},[{\"id\":\"BEL\",\"iso2Code\":\"BE\",\"name\":\"Belgium\",\"region\":{ \"id\":\"ECS\",\"value\":\"Europe & Central Asia(all income levels)\"},\"adminregion\":{ \"id\":\"\",\"value\":\"\"},\"incomeLevel\":{ \"id\":\"OEC\",\"value\":\"High income: OECD\"},\"lendingType\":{ \"id\":\"LNX\",\"value\":\"Not classified\"},\"capitalCity\":\"Brussels\",\"longitude\":\"4.36761\",\"latitude\":\"50.8371\"}]]";
var arr = JArray.Parse(str);
var rootJson = arr.ElementAt(0).ToString();
var root = JsonConvert.DeserializeObject<LandRootObject>(rootJson);
var landsJson = arr.ElementAt(1).ToString();
root.Lands = JsonConvert.DeserializeObject<List<Land>>(landsJson);
tryto change the above code to following
ms.Position = 0; // change only this line
var data = (LandRootObject)serializer.ReadObject(ms);
I have the following JSON input from a webserver:
{
"success":1,
"return":{
"45677":{
"pair":"aaaa",
"type":"bbbbbbbb",
"amount":1.00000000,
"rate":3.00000000,
"timestamp_created":1342448420,
"status":0
}
}
}
I'm using Newtonsoft JSON.net.
I have the following class:
public class ActiveOrders
{
public Dictionary<int, Order> Dictionary { get; private set; }
public static ActiveOrders ReadFromJObject(JObject o)
{
if (o == null) return null;
return new ActiveOrders
{
Dictionary =
o.OfType<KeyValuePair<string, JToken>>()
.ToDictionary(item => int.Parse(item.Key), item => Order.ReadFromJObject(item.Value as JObject))
};
}
}
It doesn't return null, which means the answers ok, as it is in my other methods. But the
result of ActiveOrders.Dictionary is empty.
Here is the class Order:
public class Order
{
public BtcePair Pair { get; private set; }
public TradeType Type { get; private set; }
public decimal Amount { get; private set; }
public decimal Rate { get; private set; }
public UInt32 TimestampCreated { get; private set; }
public int Status { get; private set; }
public static Order ReadFromJObject(JObject o)
{
if (o == null) return null;
return new Order
{
Pair = BtcePairHelper.FromString(o.Value<string>("pair")),
Type = TradeTypeHelper.FromString(o.Value<string>("type")),
Amount = o.Value<decimal>("amount"),
Rate = o.Value<decimal>("rate"),
TimestampCreated = o.Value<UInt32>("timestamp_created"),
Status = o.Value<int>("status")
};
}
}
The types are correct, as are my other classes, they all look the same.
I would like some ideas to make it work. Any advice?
Below code works.....
var obj = JsonConvert.DeserializeObject<ActiveOrders>(json);
public class ActiveOrders
{
public int success { get; set; }
public Dictionary<string,Order> #return { get; set; }
}
public class Order
{
public string pair { get; set; }
public string type { get; set; }
public double amount { get; set; }
public double rate { get; set; }
public int timestamp_created { get; set; }
public int status { get; set; }
}