For loop takes the the max count - c#

private List<SurveyDetail> GetSurveyDetails()
{
List<SurveyDetail> surveyDetails = new List<SurveyDetail>();
SurveyDetail detail = new SurveyDetail();
int cid = 0;
for (int i = 1; i < 3; i++)
{
detail.choiceId = "1";
detail.choiceDesc = "tesT";
detail.questionId = i.ToString();
surveyDetails.Add(detail);
}
return surveyDetails;
}
public class SurveyDetail
{
public string questionId { get; set; }
public string choiceId { get; set; }
public string choiceDesc { get; set; }
}
when I run the code it question Id always gives me the last number of i that was run for example, in this case, it gives me 2. It gives me 2 on both counts.
Where I want the questionid to be 1 in the first count and 2 in the second.

You should move SurveyDetail initialization into the for body
private List<SurveyDetail> GetSurveyDetails()
{
List<SurveyDetail> surveyDetails = new List<SurveyDetail>();
int cid = 0;
for (int i = 1; i < 3; i++)
{
SurveyDetail detail = new SurveyDetail();//<==NOTE THIS
detail.choiceId = "1";
detail.choiceDesc = "tesT";
detail.questionId = i.ToString();
surveyDetails.Add(detail);
}
return surveyDetails;
}

Incase you want to use : LINQ
var result = Enumerable.Range(1, 3).Select(detail => new SurveyDetail
{
choiceId = "1",
questionId = detail.ToString(),
choiceDesc = "testT",
});

Related

How can I get class Properties values saved in a List of objects and Iterate using a loop

This Is the class I have
public class Income
{
public string Code { get; set; }
public int Month1 { get; set; }
public int Month2 { get; set; }
public int Month3 { get; set; }
public int Month4 { get; set; }
public int Month5 { get; set; }
public List<Income> income { get; set; }
}
In the other class
List<Income> incomeList = new List<Income>();
//repeat twice
Income obj = new Income();
obj.Month1 = 200;
obj.Month2 = 150;
...
IncomeList.Add(obj);
obj.income = IncomeList;
Now I want to retrieve those Months in a loop for each new obj saved in a
List.
So far
Int[] results = obj.income
.Select(x=> new
{
x.Month1,
x.Month2,
x.Month3,
x.Month4,
x.Month5
})
.ToArray();
This is where I need to add the total months for each unique object.
get The total for All Months1 , Months2 ...
double totals[] = new double[5];
for (int i=0;i<results.length;i++)
{
totals[i] += results[i]; // I get the first object reference
// I want Moth1,Month2 ... to be in an indexed array where
// if i want Month1 i would access similar to : results[index];
}
Ok, the following code will project out a list of objects. Each object will have a single property called "Months" which is an int[] of the month values.
Does that do what you need?
void Main()
{
var incomeList = new List<Income>();
Income obj = new Income();
obj.Month1 = 200;
obj.Month2 = 150;
incomeList.Add(obj);
var results = incomeList
.Select(x => new
{
Months = new int[]
{
x.Month1,
x.Month2,
x.Month3,
x.Month4,
x.Month5
}
})
.ToArray();
for (int i = 0; i < results.Length; i++)
{
var testResults = results[i];
Console.WriteLine($"Month 1: {testResults.Months[0]}");
Console.WriteLine($"Month 2: {testResults.Months[1]}");
Console.WriteLine($"Month 3: {testResults.Months[2]}");
Console.WriteLine($"Month 4: {testResults.Months[3]}");
Console.WriteLine($"Month 5: {testResults.Months[4]}");
}
}
However, given your comments in the posted code, I think you want to to turn it into a 2-dimensional array. If so, simply project out an int[]:
void Main()
{
var incomeList = new List<Income>();
Income obj = new Income();
obj.Month1 = 200;
obj.Month2 = 150;
incomeList.Add(obj);
int[][] results = incomeList
.Select(x => new int[]
{
x.Month1,
x.Month2,
x.Month3,
x.Month4,
x.Month5
})
.ToArray();
for (int i = 0; i < results.Length; i++)
{
var testResults = results[i];
Console.WriteLine($"Month 1: {testResults[0]}");
Console.WriteLine($"Month 2: {testResults[1]}");
Console.WriteLine($"Month 3: {testResults[2]}");
Console.WriteLine($"Month 4: {testResults[3]}");
Console.WriteLine($"Month 5: {testResults[4]}");
}
}

Bind a linkedlist to a datagridview

I'm trying to bind a linkedlist to a datagridview. The method below works for the properties in the class except the array.
If I declare the array as a new instance the linkedlist is created correctly, but the array is not bound into the datagridview.
If the array is created as a property (I think the code is correct) causes An unhandled exception of type 'System.StackOverflowException' occurred when the linkedlist is created.
Thanks for any help.
public class PayoffNode
{
public int DealNo { get; set; }
public string Category { get; set; }
public string Strategy { get; set; }
public string GreekType { get; set; }
// declare array as instance or as a property?
//public double[] Data = new double[22];
public double[] Data
{
get { return Data; }
set { Data = value; }
}
}
LinkedList<Globals.PayoffNode> PayLL = new LinkedList<Globals.PayoffNode>();
Random Rnd = new Random();
for (int K = 1; K <= 10; K++)
{
var T = new Globals.PayoffNode();
T.Category = "Account==" + K;
T.GreekType = "Greek==" + K;
T.DealNo = K;
T.Strategy = "Strategy==" + K;
for (int DP = 1; DP <= 21; DP++)
{
T.Data[DP] = Rnd.Next(10, 99);
}
PayLL.AddLast(T);
}
List<Globals.PayoffNode> qP = (from P in PayLL
where P.Category == "Account==4" && P.DealNo == 4 && P.GreekType == "Greek==4" && P.Strategy == "Strategy==4"
select P).ToList();
PayoffTable.DataSource = qP;
Update:
Thanks for the comments, this seems to be working.
public class PayoffNode
{
public int DealNo { get; set; }
public string Category { get; set; }
public string Strategy { get; set; }
public string GreekType { get; set; }
public double Data1 { get; set; }
public double Data2 { get; set; }
public double Data3 { get; set; }
public double[] Data = new double[22];
}
LinkedList<Globals.PayoffNode> PayLL = new LinkedList<Globals.PayoffNode>();
Random Rnd = new Random();
for (int K = 1; K <= 10; K++)
{
var T = new Globals.PayoffNode();
T.Category = "Account==" + K;
T.GreekType = "Greek==" + K;
T.DealNo = K;
T.Strategy = "Strategy==" + K;
for (int DP = 1; DP <= 21; DP++)
{
T.Data[DP] = Rnd.Next(10, 99);
}
PayLL.AddLast(T);
}
List<Globals.PayoffNode> qP = (from P in PayLL
where P.Category == "Account==4" && P.DealNo == 4 && P.GreekType == "Greek==4" && P.Strategy == "Strategy==4"
select new Globals.PayoffNode()
{
Category=P.Category,
DealNo=P.DealNo,
GreekType=P.GreekType,
Strategy=P.Strategy,
Data1=P.Data[1],
Data2 = P.Data[2],
Data3 = P.Data[3],
}).ToList();
PayoffTable.DataSource = qP;
One way to avoid making 21 Data properties is to convert the List to DataTable:
class PayoffNode
{
public int DealNo;
public string Category;
public double[] Data; // = new double[21];
}
and then
Random Rnd = new Random();
List<PayoffNode> PayLL = Enumerable.Range(1, 10).Select(i => new PayoffNode {
DealNo = i,
Category = "Account==" + i,
Data = Enumerable.Range(1, 21).Select(d => (double)Rnd.Next(10, 99)).ToArray()
}).ToList();
// List<PayoffNode> to DataTable
var dt = new DataTable();
dt.Columns.Add("DealNo", typeof(int));
dt.Columns.Add("Category"); // typeof(string) by default
for (int i = 1; i <= 21; i++)
dt.Columns.Add("Data" + i, typeof(double));
foreach (var P in PayLL)
{
var dr = dt.Rows.Add(P.DealNo, P.Category);
for (int i = 0; i < 21; i++)
dr[i+2] = P.Data[i]; // +2 is the number of fields before the Data fields
}
PayoffTable.DataSource = dt;
dt.DefaultView.RowFilter = " Category = 'Account==4' ";
The advantage is that you set the DataSource only once and just change the RowFilter to filter it. Also, any changes made in the DataGridView change the DataTable and vice-versa.
Note that arrays in C# and most other languages start from 0 and not from 1 ( .Data[0] to access the first item in the array ), so the for loop to access the Data array in my example is from 0 to 20.
public double[] Data
{
get { return Data; }
set { Data = value; }
}
This is the problem, the object in the set and get method needs to refer to a different object otherwise whenever the object value is set or trying to be retrieved it will just keep calling these methods infinitely. should be...
private double[] _data;
public double[] Data
{
get { return _data; }
set { _data = value; }
}
or...
public double[] Data { get; set; }

Loop object creation

I need to have my second nested for loop send the array values to class friends.
I do not know how I would go about this?
Unless I missed something in the class?
namespace List
{
class Program
{
public const int ARRAYSIZE = 5;
static void Main()
{
string[] relSend = { "Enter name", "enter phone number", "enter 2 didigt month dob", "enter 2 digit day dob", "enter 2 digit dob year" };
string[] In = new string[5];
string[] answer = new string[10];
for (int x = 0; x <= 8; x++)
{
for (int i = 0; i < relSend.Length; i++)
{
WriteLine("{0}", relSend[i]);
In[i] = Console.ReadLine();
}
for (int i = 0; i < In.Length; i++)
{
}
}
}
}
}
public class Friends
{
public string Name { get; set; }
public int Phone { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}
I guess you mean you want to create an object out of the information collected, that is no problem:
List<Friend> friends = new List<Friend>();
for (int x = 0; x <= 8; x++)
{
for (int i = 0; i < relSend.Length; i++)
{
WriteLine("{0}", relSend[i]);
In[i] = Console.ReadLine();
}
friends.Add( new Friend() { Name = In[0]
, Phone = int.Parse(In[1])
, Month = int.Parse(In[2])
, Day = int.Parse(In[3])
, Year = int.Parse(In[4])
}
);
}
Make sure to validate the input before creating the object! Also, I would suggest to use string for a phone number since you would lose the 0 that is the usual prefix. Month, Day and Year might be combined in a single DateTime.
Tell me if you need any explanations:
namespace List
{
class Program
{
//Create a dictionary to find out each question is realated to which property.
private static Dictionary<string, string> questions = new Dictionary<string, string>();
static void Main()
{
questions.Add("Enter name", "Name");
questions.Add("enter phone number", "Phone");
questions.Add("enter 2 didigt month dob", "Month");
questions.Add("enter 2 digit day dob", "Day");
questions.Add("enter 2 digit dob year", "Year");
//Create list of friends
List<Friends> friendsList = new List<Friends>();
for (int x = 0; x <= 8; x++)
{
Friends f = new Friends();
foreach (string q in questions.Keys)
{
Console.WriteLine("{0}", q);
//Find property using Sytem.Reflection
System.Reflection.PropertyInfo property = f.GetType().GetProperty(questions[q]);
//Set value of found property
property.SetValue(f, Convert.ChangeType(Console.ReadLine(), property.PropertyType), null);
}
//Add a friend to list
friendsList.Add(f);
}
}
}
}
public class Friends
{
public string Name { get; set; }
public int Phone { get; set; }
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}

list class property in a class c# assign value

class Program
{
static void Main(string[] args)
{
Posting onjPosting = null;
List<Posting> objList = null;
for (int i = 0; i < 100; i++)
{
onjPosting = new Posting();
onjPosting.Key1 = i;
for (int j = 0; j < 5; i++)
{
Choice objChoice = new Choice();
objChoice.ID = i;
objChoice.VAL = j;
onjPosting.GetPostingChoice.Add(objChoice); // GETTING ERROR [ Object reference not set to an instance of an object. ]
}
objList.Add(onjPosting);
}
}
}
public class Choice
{
public int ID { get; set; }
public int VAL { get; set; }
}
public class Posting
{
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
}
While looping through and assigning the value I am getting error . How to solve this ? Please help me out .
My requirement is one parent class (Posting) , can contain number of data List .
Thanks in advance .
You never allocate the GetPostingChoice list so of course it is null.
You could do it in the constructor:
public class Posting
{
public Posting()
{
GetPostingChoice = new List<Choice>();
}
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
}
Add a public constructor on your Posting class:
public class Posting
{
public int Key1 { get; set; }
public List<Choice> GetPostingChoice { get; set; }
public Posting()
{
GetPostingChoice = new List<Choice>();
}
}
You also have other errors:
You do not initialize objList, so you cannot add in there.
List<Posting> objList = null;
So you will get another Null Reference when you get to:
List<Posting> objList = null;
In your second loop you increase i instead of j so it will never end.
for (int j = 0; j < 5; i++)
This is how it should look:
Posting onjPosting = null;
List<Posting> objList = new List<Posting>();
for (int i = 0; i < 1; i++)
{
onjPosting = new Posting();
onjPosting.Key1 = i;
for (int j = 0; j < 5; j++)
{
Choice objChoice = new Choice();
objChoice.ID = i;
objChoice.VAL = j;
onjPosting.GetPostingChoice.Add(objChoice); // GETTING ERROR [ Object reference not set to an instance of an object. ]
}
objList.Add(onjPosting);
}
Since you ask for another approach, and this is just one of the many ways you could do it, have a look at this:
List<Posting> objList = new List<Posting>();
Enumerable.Range(0,100)
.Select
(
(x,i)=>new Posting
{
Key1 = i,
GetPostingChoice = Enumerable.Range(0,5).Select((p,j)=>new Choice{ID = i,VAL = j}).ToList()
}
);

Combining numbers and names collections

I have 2 List collections. One contains numbers, the other names. There are twice as many numbers as names(always). I want to take the first name from the collection and the first two numbers from the other collection then put them together in a 3rd user collection of (VentriloUser). Then the second name needs to be matched with the 3rd and 4th numbers and so on.
I was thinking something with a for or foreach loop, but I can't wrap my head around it right now.
public class VentriloUser
{
public VentriloUser(string name, int seconds, int ping)
{
Name = name; Seconds = seconds; Ping = ping;
}
public string Name { get; set; }
public int Ping { get; set; }
public int Seconds { get; set; }
}
public class Ventrilo
{
public Ventrilo(string statusurl)
{
StatusURL = statusurl;
}
public string StatusURL { get; set; }
public string HTML { get; set; }
public List<VentriloUser> Users { get; set; }
private Regex findNumbers = new Regex("\\<td width=\"10%\" bgcolor=\"#\\w{6}\"\\>\\<font color=\"#000000\">\\<div style=\"overflow:hidden;text-overflow:ellipsis\"\\>-?\\d+\\<");
private Regex findNames = new Regex("\\<td width=\"20%\" bgcolor=\"#\\w{6}\"\\>\\<font color=\"#000000\">\\<div style=\"overflow:hidden;text-overflow:ellipsis\"\\>\\b\\w+\\<");
private WebClient wClient = new WebClient();
public void DownloadHTML()
{
HTML = wClient.DownloadString(StatusURL);
}
public List<int> GetNumbers()
{
var rawnumbers = findNumbers.Matches(HTML);
var numbers = new List<int>();
foreach (var rawnumber in rawnumbers)
{
var match = Regex.Match(rawnumber.ToString(), "\\>\\-?\\d+\\<");
string number = Regex.Replace(match.ToString(), "\\<|\\>", "");
numbers.Add(Convert.ToInt32(number));
}
return numbers;
}
public List<string> GetNames()
{
var rawnames = findNames.Matches(HTML);
var names = new List<string>();
foreach (var rawname in rawnames)
{
var match = Regex.Match(rawname.ToString(), "\\>\\w+<");
string name = Regex.Replace(match.ToString(), "\\<|\\>", "");
names.Add(name);
}
return names;
}
public List<VentriloUser> GenerateUsers()
{
var numbers = GetNumbers();
var names = GetNames();
var users = new List<VentriloUser>();
}
}
I am a hobbyist, but hope to pursue a career one day. Any help is much appreciated. Thank you for your time.
Using LINQ:
var users = names.Select((name,idx) => new VentriloUser(name, numbers[idx*2], numbers[idx*2+1]))
.ToList();
Using loops:
var users = new List<VentriloUser>();
for (int i = 0; i < names.Count; i++)
{
var name = names[i];
int j = i * 2;
if (j >= numbers.Count - 1)
break; // to be safe...
users.Add(new VentriloUser(name, numbers[j], numbers[j + 1]));
}

Categories