Add values to a list within a foreach loop - c#

I simply wanted to add float values to list within a foreach loop. The code perfectly reads row.Size as well as row.Price and adds additional RData1 sets to InDat, but uses always the "latest" dataset of RData1.Size and RData1.Price instead of keeping the "previous" loop values. So after closing the loop, I get the same values in each line of the list.
IEnumerable<ModelInput> inputData = mlC.Data.CreateEnumerable<ModelInput>(tView,reuseRowObject: true);
public List<InputData> InDat { get; set; }
InDat = new List<InputData>();
InputData RData1 = new InputData();
int count = 0;
foreach (ModelInput row in inputData)
{
count++;
RData1.Size = Convert.ToString(row.Size);
RData1.Price = Convert.ToString(row.Price);
InDat.Add(RData1);
}

You need to instantiate Rdatat1 inside the loop:
int count = 0;
foreach (ModelInput row in inputData)
{
count++;
InputData RData1 = new InputData();
RData1.Size = Convert.ToString(row.Size);
RData1.Price = Convert.ToString(row.Price);
InDat.Add(RData1);
}

Related

How to loop list class

I have below class. And data is serialized using JsonConvert.DeserializeObject. The data is returning from list. But I want to loop using for or for each. Please advice.
Thank you.
var result = client.getInvocieLine
(call Context);
string strResultJson = JsonConvert.SerializeObject(result);
System.IO.File.WriteAllText(#"D:\jsondata\invoicedata.json", strResultJson);
string fileName = #"D:\jsondata\invoicedata.json";
string jsonText = System.IO.File.ReadAllText(fileName)
List<EInvoiceModel.Class1> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<EInvoiceModel.Class1>>(jsonText);
EInvoiceModel.Invoiceline invoicelined = new EInvoiceModel.Invoiceline();
for(int i=0; i < data.Count; i++)
{
invoicelined.parmItemId = data[i].invoiceLines[i].parmItemId; //Its bring only one record. I need all record from data. Please advice.
}
return Ok(invoicelined);
Please find my EInvoiceModel contains below structure, Which i designed as per my json response. yes I need same index for data and invoiceLines in data[i].invoiceLines[i]. How can I get this to return all values. Index currently pointing only one record and return one record. If I change position its return another record. But I need all please.
public class Class1
{
public Invoiceline[] invoiceLines { get; set; }
public string parmCustName { get; set; }
public DateTime parmInvoiceDate { get; set; }
} public class Invoiceline
{
public string parmItemId { get; set; }
public string parmItemNameDisplay { get; set; }
public float parmQty { get; set; }}
Please find my json structure. I wist to repeat all parameter-ids from json response.
{"invoiceLines":[{"parmCurrencyCode":null,"parmCustExchRate":0.0,"parmInvoiceId":null,"parmItemId":null,"parmItemNameDisplay":null,"parmQty":0.0,"parmSalesLinePercent":0.0,"parmSalesUnit":null,"parmdiscountAmount":0.0,"parmnetTotal":0.0,"parmsalesPrice":0.0,"parmsalesTotal":0.0,"parmtotalItemsLineDisc":0.0,"parmtotalTaxableFees":0.0}],"parmCustName":null,"parmInvoiceDate":"0001-01-01T00:00:00","parmInvoiceId":null,"parmSalesId":null,"parmnetAmount":0.0,"parmtotalAmount":0.0,"parmtotalAmountWithDisc":0.0,"parmtotalItemsDiscountAmount":0.0,"parmtotalSalesAmount":0.0}
Please I want return all parmItemId below way. I don't want damage my json structure.
EInvoiceModel.Class1 ds = new EInvoiceModel.Class1();
List<EInvoiceModel.Class1> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<EInvoiceModel.Class1>>(jsonText);
// List<EInvoiceModel.Invoiceline> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<EInvoiceModel.Invoiceline>>(jsonText);
for (int i = 0; i < data.Count; i++)
{
ds.invoiceLines = new List<EInvoiceModel.Invoiceline>
{
new EInvoiceModel.Invoiceline
{
parmItemId = data[i].invoiceLines[i].parmItemId
}
};
}
return Ok(ds);
You have used to Generic list
To get all list
List<EInvoiceModel.Invoiceline> data = Newtonsoft.Json.JsonConvert.DeserializeObject<List<EInvoiceModel.Invoiceline>>(jsonText);
List<EInvoiceModel.Invoiceline> invoicelines = new List<EInvoiceModel.Invoiceline>();
for(int i=0; i < data.Count; i++)
{
invoicelines.Add(new EInvoiceModel.Invoiceline()
{
parmItemId = data[i].parmItemId
});
}
return Ok(invoicelines);
You now have this:
EInvoiceModel.Class1 ds = new EInvoiceModel.Class1();
for (int i = 0; i < data.Count; i++)
{
ds.invoiceLines = new List<EInvoiceModel.Invoiceline>
{
new EInvoiceModel.Invoiceline
{
parmItemId = data[i].invoiceLines[i].parmItemId
}
};
}
This means that on every iteration you overwrite that ds.invoiceLines with a new list, containing a single item. So you end up with only the last one.
A possibly better way would be this:
EInvoiceModel.Class1 ds = new EInvoiceModel.Class1();
ds.invoiceLines = new List<EInvoiceModel.Invoiceline>(); // create a list once
for (int i = 0; i < data.Count; i++)
{
// add one item to that list
ds.invoiceLines.Add(new EInvoiceModel.Invoiceline
{
parmItemId = data[i].invoiceLines[i].parmItemId
}
);
}
This way you assign a new (empty) list once (you can skip this when invoiceLines already contains an empty list, after you created a new Class1).
And then, in the loop, you don't assign a new list, but just add a new item to that existing list. At the end, you get a list with as many items as there are in your input data.
By the way, this assumes that you really need to make a list of data[i].invoiceLines[i].parmItemId. I find it curious that for data[3] you need an invoiceLines[3] and for data[7] an invoiceLines[7]. I would expect one loop through all data and then an inner loop over all its invoiceLines. But you know your data best.
Apparently, you do need to loop over the inner objects. So modify that code like this:
EInvoiceModel.Class1 ds = new EInvoiceModel.Class1();
ds.invoiceLines = new List<EInvoiceModel.Invoiceline>(); // create a list once
// loop over all "data" items
for (int i = 0; i < data.Count; i++)
{
// then loop over the invoiceLines inside the current data item
for (int j = 0; j < data[i].invoiceLines.Count(); j++)
{
// add one item to that list
ds.invoiceLines.Add(new EInvoiceModel.Invoiceline
{
parmItemId = data[i].invoiceLines[j].parmItemId
}
);
}
}
Note that I still use index i in data[i] from the outer loop, but now use index j in invoiceLines[j] from the inner loop.

Resetting the order in schedules

The goal of this macros (app) is to reset the order of elements inside of a schedule we have opened now. Order starts with a user chosen number. Numbers are stored inside every element's parameter that user can specify. We get IDs of elements by hitting "IDs of Selection".
Resetting the order
public void AutoNumerate()
{
Document doc = this.ActiveUIDocument.Document;
ViewSchedule vs = doc.ActiveView as ViewSchedule;
TableData tData = vs.GetTableData();
TableSectionData tsDada = tData.GetSectionData(SectionType.Body);
int startIndex = 1; //SETTING STARTING NUMBER
using (TransactionGroup tGroup = new TransactionGroup(doc,"Numeration: "+vs.Name))
{
tGroup.Start();
for (int rInd = 0; rInd < tsDada.NumberOfRows; rInd++)
{
SetNum(doc,startIndex++, );
}
tGroup.Assimilate();
}
}
public void SetNum(Document doc, int num, List<Element> Myelements)
{
using (Transaction tr = new Transaction(doc,"Creating elements based on IDs"))
{
tr.Start();
//List<ElementId> eleIds = new List<ElementId>{946164,946385,946484,946631,946708,946759,946816};
int[] eleIds = {946164,946385,946484,946631,946708,946759,946816};
foreach (int id in eleIds)
{
List<Element> MyElements = GetElement();
}
foreach (Element ele in MyElements)
{
//ele.LookupParameter("Comments").Set(num.ToString());
ele.LookupParameter("Comments").Set(num.ToString()).ToList(); //SPECIFYING PARAMETER
}
tr.Commit();
}
}
private List<Element> GetElementsOnRow(Document doc, ViewSchedule vs, int rowNumber)
{
TableData tableData = vs.GetTableData();
TableSectionData tableSectionData = tableData.GetSectionData(SectionType.Body);
To sort a schedule you need to use the ScheduleDefinition.AddSortGroupField method. Create a ScheduleSortGroupField from the ScheduleFieldId of the 'Comments' parameter to input into the method.

How to fix extra run in loop?

I create an object in which values from 3 rows and I need to loop through 3 lines and add values from this object (rowsCmd).
private void CalculateDist()
{
var Unique= Cursor.GetFieldValue<int>("Unique");
var document = new HeadersRepository().Get(Unique);
if (document == null)
{
return;
}
var rowsRepository = new RowsRepository(document);
var rowList = rowsRepository.GetRows();
var cmd = SqlClient.Main.CreateCommand(string.Format(
#"select DOC.Unique, DOC.Number from DOC where DOC.Unique =#Unique order by DOC.Number"), new { Unique });
var rowsCmd = cmd.ExecObjects(new
{
Unique= 0,
Number= 0,
});
foreach (var row in rowList)
{
foreach (var rowCmd in rowsCmd)
{
row.Number = rowCmd.Number;
row.Number= rowCmd.Number;
}
}
}
if i have 2 rows this code will execute 4 time, but need only 2. how to make a loop which will pass through each rows in my list rowList and put data from object rowsCmd in 1 loop
Your code always set row values with rowsCmd list's last element. So it is a wrong code segment.
For your purpose you can use for loop instead of foreach loop.
for(int i=0; i< rowList.Count; i++){
rowList[i].Number = rowsCmd[i].Number;
}

Foreach going out of bounds while searching through array c#

The purpose of my program is to take a data txt file and edit it, and/or make additions and subtractions to it.
The text file format is like this:
Name|Address|Phone|# of people coming|isRSVP
The code I have seems to be doing it's job all the way up until I try to click one of the names within a listbox and it needs to search through the multidimensional array to pull information out and place within a set of textboxes where they can be edited. The problem is that the foreach loop I use gives me an out of bounds exception. I tried to do a step into debug to make sure the data is correct in the array and see the process. Everything seems to do correctly but for some reason in the conditional statement person[0]==listbox1.selectedIndex isn't returning true even though both are the same as I seen through the step into process. Any help would be greatly appreciated.
This is my code:
StringBuilder newFile = new StringBuilder();
static string txtList= "guest_list.txt";
static string[] file = File.ReadAllLines(txtList);
static int x = file.Count();
string[,] list = new string[x ,5];
public void loadGuestList()
{
int count2 = 0;
foreach (string line in file)
{
string[] sliced = line.Split('|');
int count = 0;
list[count2, count] = sliced[0];
count++;
list[count2, count] = sliced[1];
count++;
list[count2,count] = sliced[2];
count++;
list[count2,count]= sliced[3];
count++;
list[count2, count] = sliced[4];
count++;
listBox1.Items.Add(list[count2,0]);
count2++;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (string person in list)
{
if ( person[0].ToString()==listBox1.SelectedItem.ToString())
{
addTxt.Text = char.ToString(person[1]);
textPhone.Text = char.ToString(person[2]);
textPeople.Text = char.ToString(person[3]);
if (person[4] == 'n' )
{
}
else
{
chkRSVP.Checked = true;
}
break;
}
}
}
The problem lies in this line:
foreach (string person in list)
The list is defined as being string[,] which when you for each over will do every element, not just the column of data. You really should do something such as:
for(int index = 0; index <= list.GetUpperBound(0); index++)
{
string slice1 = list[index, 0];
string slice2 = list[index, 1];
....
}
or switch to using a Dictionary<string, string[]>().
Try to use a "Person" object and override equals(). Right now you're trying to put your multidimensional array (list[0]) into a string, it'll give you a unwanted result. You should use list[0,0] instead.
In agreement with Adam Gritt, I tested the following code and it seemed to work:
using System;
namespace so_foreach_bounds
{
class MainClass
{
public static void Main (string[] args)
{
//System.Text.StringBuilder newFile = new System.Text.StringBuilder();
string txtList= "guest_list.txt";
string[] file = System.IO.File.ReadAllLines(txtList);
int x = file.Length;
System.Collections.Generic.List<string[]> list = new System.Collections.Generic.List<string[]> ();
foreach (string line in file)
{
string[] sliced = line.Split('|');
list.Add(sliced);
}
foreach (string[] person in list)
{
Console.WriteLine (String.Join(", ", person));
if (person[0] =="Gary")
{
string txtAdd = person[1];
string txtPhone = person[2];
string txtpeople = person[3];
if (person[4] == "n" )
{
}
else
{
bool has_resvped = true;
}
break;
}
}
}
}
}
The issue is how you are iterating over the 2d array. It is usually a better idea to create a "Person" class, than try to manage it via arrays though. Oh yes, and it's usually a good idea to check that a list box item is selected before attempting to use one of its members.

How do I make List of Lists? And then add to each List values?

class ExtractLinks
{
WebClient contents = new WebClient();
string cont;
List<string> links = new List<string>();
List<string> FilteredLinks = new List<string>();
List<string> Respones = new List<string>();
List<List<string>> Threads = new List<List<string>>();
public void Links(string FileName)
{
HtmlDocument doc = new HtmlDocument();
doc.Load(FileName);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
HtmlAttribute att = link.Attributes["href"];
if (att.Value.StartsWith("http://rotter.net/forum/scoops1"))
{
links.Add(att.Value);
}
}
for (int i = 0; i < links.Count; i++)
{
int f = links[i].IndexOf("#");
string test = links[i].Substring(0, f);
FilteredLinks.Add(test);
}
for (int i = 0; i < FilteredLinks.Count; i++)
{
contents.Encoding = System.Text.Encoding.GetEncoding(1255);
cont = contents.DownloadString(FilteredLinks[i]);
GetResponsers(cont);
}
}
private void GetResponsers(string contents)
{
int f = 0;
int startPos = 0;
while (true)
{
string firstTag = "<FONT CLASS='text16b'>";
string lastTag = "&n";
f = contents.IndexOf(firstTag, startPos);
if (f == -1)
{
break;
}
int g = contents.IndexOf(lastTag, f);
startPos = g + lastTag.Length;
string responser = contents.Substring(f + firstTag.Length, g - f - firstTag.Length);
foreach (List<string> subList in Threads)
{
}
}
}
}
I created this variable :
List<List<string>> Threads = new List<List<string>>();
The first thing I don't know yet how to do is how to create inside Threads number of Lists according to the FilteredLinks.Count inside the Links method.
Second thing is in the GetResponsers method I did:
foreach (List<string> subList in Threads)
{
}
But what I want is that first time it will add all the values from variable responser to the first List in Threads. Then when it's getting to the break; it stop then and then in the Links methods its calling GetResponsers(cont); again this time I want that all the values in responser to be added to the second List in Threads.
I know that each time it's getting to the break; it will get the next FilteredLink from FilteredLinks.
How do I create number of Lists in Threads according to the FilteredLinks.Count?
How do I make the code in GetResponsers to add the responser ?
You don't need to specify the count for the number of lists in Threads, since it is a list, you can simply keep adding lists to it. So the first part is correct where you are declaring it.
The second part --> Your calling method will change. Look below for the calling method.
The third part --> Change private void GetResponsers(string contents) to private void GetResponsers(List threadList, string contents). Look below for implementation change.
Also the loop will look like this then
//other code you have
List<List<string>> Threads = new List<List<string>>();
public void Links(string FileName)
{
// ...other code you have
for (int i = 0; i < FilteredLinks.Count; i++)
{
threads.Add(new List<string>);
contents.Encoding = System.Text.Encoding.GetEncoding(1255);
cont = contents.DownloadString(FilteredLinks[i]);
GetResponsers(threads[threads.Count - 1], cont);
}
}
private void GetResponsers(List<string> threadList, string contents)
{
int f = 0;
int startPos = 0;
while (true)
{
string firstTag = "<FONT CLASS='text16b'>";
string lastTag = "&n";
f = contents.IndexOf(firstTag, startPos);
if (f == -1)
{
break;
}
int g = contents.IndexOf(lastTag, f);
startPos = g + lastTag.Length;
string responser = contents.Substring(f + firstTag.Length, g - f - firstTag.Length);
threadList.Add(responser);
}
}
PS: Please excuse the formatting.
How do i make List of Lists ? And then add to each List values?
The following codesnippet demonstrates you, how to handle List<List<string>>.
List<List<string>> threads = new List<List<string>>();
List<string> list1 = new List<string>();
list1.Add("List1_1");
list1.Add("List1_2")
threads.Add(list1);
List<string> list2 = new List<string>();
list1.Add("List2_1");
list1.Add("List2_2")
list1.Add("List2_3")
threads.Add(list2);
How do i create number of Lists in Threads according to the
FilteredLinks.Count ?
for(int i = 0; i < FilteredLinks.Count; i++)
{
var newList = new List<string>();
newList.Add("item1"); //add whatever you wish, here.
newList.Add("item2");
Threads.Add(newList);
}
I'm afraid I can't help you with Question #2, since I don't understand what you try to achieve there exactly.

Categories