I am creating an Array using List in C#. List data coming from a web service. I am using this array to create a table in PDF(spire.pdf). I want to add a header every 15th element. I can add the first one. From my method header value replaced an element in the array afterwords.
For example if I have 35 element in the list and I want to add the first row as the header row rankListArray[i] = "No;" + "BRN;" + "Exp.Date;" + "Vehicle No;" + "Policy No;" + "Name of Insured;" + "Additional Covers;" + "Sum Insured;" + "NCB;" + "Amount Due"; to the array.
Then in the 15th position again I need to add this row. Then in the 30th position
public class PrintedMotorRenewalCompactData
{
public string DUE_DATE { get; set; }
public string CUST_NAME { get; set; }
public string POLICY_NO { get; set; }
public string VEHI_NO { get; set; }
public double NCB_PERC { get; set; }
public double SUM_INS { get; set; }
public double PRM_AMT { get; set; }
public string COVERS { get; set; }
public int BRANCH { get; set; }
public string BRANCH_NAME { get; set; }
public string POL_STAT { get; set; }
}
IList<PrintedMotorRenewalCompactData> rankList;
for (int i = 0; i < rankList.Count; i++)
{
if ((i % 15) == 0) {
rankListArray[i] = "No;" + "BRN;" + "Exp.Date;" + "Vehicle No;" + "Policy No;" + "Name of Insured;" + "Additional Covers;" + "Sum Insured;" + "NCB;" + "Amount Due";
rankListArray[i + 1] =
(i + 1) + ";" +
rankList[i].BRANCH + ";" +
rankList[i].DUE_DATE + ";" +
rankList[i].VEHI_NO + ";" +
rankList[i].POLICY_NO + ";" +
rankList[i].CUST_NAME + ";" +
rankList[i].COVERS + ";" +
rankList[i].SUM_INS.ToString("N", CultureInfo.InvariantCulture) + ";" +
rankList[i].NCB_PERC + ";" +
rankList[i].PRM_AMT.ToString("N", CultureInfo.InvariantCulture);
} else {
rankListArray[i + 1] =
(i + 1) + ";" +
rankList[i].BRANCH + ";" +
rankList[i].DUE_DATE + ";" +
rankList[i].VEHI_NO + ";" +
rankList[i].POLICY_NO + ";" +
rankList[i].CUST_NAME + ";" +
rankList[i].COVERS + ";" +
rankList[i].SUM_INS.ToString("N", CultureInfo.InvariantCulture) + ";" +
rankList[i].NCB_PERC + ";" +
rankList[i].PRM_AMT.ToString("N", CultureInfo.InvariantCulture);
}
}
Let's simplify you issue. I will assume that you are to produce a List<string> from your List<customObject>.
We start with a List with all letters of the alphabet. We will insert a header every 3 rows.
var header = "Hi, I'm Header!";
var headerRepeatsEvery = 3.0; // .0 to avoid int division.
var inputs = Enumerable.Range((int)'A', 26).Select(x => ((char)x).ToString()).ToList();
Writing a part of exected result we have :
Header!
1;A
2;B
3;C
Header!
4;D
5;E
The header are in index : {0,4,8,12,16, .. etc}
That look like : X * 4
Let's try to find how many of those header we will need :
List Size | Header Count
0 0
1 1
2 1
3 1
4 2
A simple division won't give use the result 4/3 = 1.3333.
We need to round it to the next int, and that's Math.Ceiling
Now the rest is simple for every Header index, we have to insert the header.
foreach (var index in headerIndexes)
{
alpha.Insert(index, headerText);
}
Now we have our expected result we just need to make it a array : ToArray().
Online Demo
Your final code may look like this :
var csvLikeLines = rankList.Select((x, i) => $"{i + 1};{x.property1};{x.property2}"));
var indexes = Enumerable.Range(0,(int)Math.Ceiling(csvLikeLines.Count()/ 15))
.Select(x => x * 16);
foreach (var index in indexes)
{
csvLikeLines.Insert(index, headerTest);
}
rankListArray = csvLikeLines.ToArray();
I will recommend using something more rebust for concataining property value with ';' semi colon. Soon enought one of the value will have a \n, \r, or semi colon and everything will go boom.
As you are using it to create a report the strongest argument for using a mapper like CsvHelper is that you will be able to arrange the column order, delete, or rename one. Without going through the nightmareof remembering that column 7 is 'propertyFoo'. it will keep the header and the column easly maintanable.
Related
I have, code who do for me "x + y = z"
if (command.Contains("+")) // string polecenie = "";'
{
polecenie = "{" + command + ")";
polecenie = polecenie.Replace("+", "}(");
double a = Convert.ToDouble(Between(polecenie, "{", "}"));
double b = Convert.ToDouble(Between(polecenie, "(", ")"));
double wyn = a + b;
richTextBox1.Text += a + " + " + b + " is " + wyn + "\r\n";
}
And when 'command' is "4+5","3 + 4" or something like this code works, but when i try to do "4 + 3 + 23" it don't work. Final string with starting 'command' "4+5+6", polecenie is: "{4}(5}(6)"... The Between Method:
public string Between(string content, string First, string Last)
{
string end = "";
int Plc1 = content.IndexOf(First) + First.Length;
int Plc2 = content.IndexOf(Last);
end = content.Substring(Plc1, Plc2 - Plc1);
return end;
}
How can I do that? (I want it to work with all possible additions ("4+4","34+5+54","43+4+65+54"...)
You could use the DataTable object to not re-invent the wheel.
richTextBox1.Text = string.Format("{0} is {1}\r\n", command,
(new System.Data.DataTable()).Compute(command, string.Empty));
This would support +, -, *, / and % (mod) operators. For more: https://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx
Hi I have an application in C# .NET where a person can submit an abstract. It will be a paragraph.
Now if I made any changes on that abstract from my end, It should send the email to that person with the Original abstract and modified abstract. Where in Modified section it should highlight the changes done.
I have written a function for this:
public string[] compareText(string submittedValue,string updatedValue)
{
#region COMPARETEXT
List<string> oldAbstract = submittedValue.Split('.').ToList<string>();
List<string> newAbstract = updatedValue.Split('.').ToList<string>();
string resultOldAbstract = "";
string resultNewAbstract = "";
for (var i = 0; i < (oldAbstract.Count - 1); i++)
{
if (String.Equals(oldAbstract[i], newAbstract[i], StringComparison.Ordinal))
{
resultOldAbstract += oldAbstract[i].ToString() + ".";
resultNewAbstract += newAbstract[i].ToString() + ".";
}
else
{
List<string> oldAbstract1 = oldAbstract[i].Split(' ').ToList<string>();
List<string> newAbstract1 = newAbstract[i].Split(' ').ToList<string>();
if (oldAbstract1.Count == newAbstract1.Count)
{
for (var j = 0; j < (oldAbstract1.Count); j++)
{
if (String.Equals(oldAbstract1[j], newAbstract1[j], StringComparison.Ordinal))
{
if (j < (oldAbstract1.Count - 1))
{
resultOldAbstract += oldAbstract1[j].ToString() + " ";
resultNewAbstract += newAbstract1[j].ToString() + " ";
}
else
{
resultOldAbstract += oldAbstract1[j].ToString() + ".";
resultNewAbstract += newAbstract1[j].ToString() + ".";
}
}
else
{
if (j < (oldAbstract1.Count - 1))
{
resultOldAbstract += oldAbstract1[j].ToString() + " ";
resultNewAbstract += "<span style='background:yellow'>" + newAbstract1[j].ToString() + "</span> ";
}
else
{
resultOldAbstract += oldAbstract1[j].ToString() + ".";
resultNewAbstract += "<span style='background:yellow'>" + newAbstract1[j].ToString() + "</span>.";
}
}
}
}
else
{
resultOldAbstract += oldAbstract[i].ToString() + ".";
resultNewAbstract += "<span style='background:yellow'>" + newAbstract[i].ToString() + "</span>.";
}
}
}
//return resultOldAbstract,resultNewAbstract;
return new[] {resultOldAbstract,resultNewAbstract};
#endregion
}
but it only works when the size of both list are same. For e.g.
****Submitted abstract****
hi This is John. i am 26 year old. I live in New York.
****Updated abstract****
Hi This is John. I am 26 year old. I live in washington.
when I do these changes then It works fine. It highlights the changes done at hi, i, New York.
Here the submitted list and updated list both have same number of elements ( here it is 3 , bcz i am splitting at fullstop '.'). But suppose in my update abstract I add a new line or remove a line:
****Updated abstract****
Hi This is John. I am 26 year old. I live in washington. I am a software engineer.
or
****Updated abstract****
Hi This is John. I am 26 year old.
then it does not work because the size of list is different and in for loop it throws index error.
Any thoughts ?
I'm trying to make a recursive algorithm that returns all possibilities of writing a given number as a sum of distinct numbers.
For example, if the given number is 8, my program should return (1,7)(1,2,5)(1,3,4)(2,6)(3,5).
As far as I worked all I could get is (for this example)(1,7)(1,(2,5)(3,4))(2,6)(3,5), and the combinations are even more imbricated as the given number is higher. How can I have the right result instead of mine?
The function is:
public String calculate(float number, float i)
{
String str = "";
float half = number / 2;
while ( i < half)
{
float diff = number - i;
str = str + "(" + i + "," + diff + ")";
if (calculate(diff, i + 1) != "")
str = str + "(" + i + "," + calculate(diff, i + 1) + ")";
i++;
}
return str;
}
The call of the function is calculate(number,1). Thank you in advance for your help!
Here's a sample program that I based on a Java answer here on SO. I modified it to display only sums with distinct values, based on your requirements. You can modify it to return a concatenated string, instead of just writing the sums out.
class Program
{
static void Main(string[] args)
{
DisplayDistinctSums(8f);
}
static void DisplayDistinctSums(float baseNum)
{
DisplayDistinctSums(baseNum, baseNum - 1, "(");
}
static void DisplayDistinctSums(float baseNum, float nextNum, string sumString)
{
if (baseNum < 1)
{
sumString += ")";
Console.WriteLine(sumString);
return;
}
for (var i = Math.Min(nextNum, baseNum); i >= 1; i--)
{
if (!sumString.Contains(i.ToString()))
{
DisplayDistinctSums(baseNum - i, i,
sumString.Length == 1 ? sumString + i : sumString + ", " + i);
}
}
}
}
Input: 8
Output:
(7, 1)
(6, 2)
(5, 3)
(5, 2, 1)
(4, 3, 1)
public string completeHour(string theTime)
{
string total="";
string[] timeArray = theTime.Split(new[] { ":" }, StringSplitOptions.None);
string h = timeArray[0];
string i = timeArray[1];
string j = timeArray[2];
MessageBox.Show(h + "+" + i + "+" + j);
if (h == " " || i == " " || j == " ")
{
if (h == " ")
{
h = "00";
total = (String.Concat("00",theTime)).Trim();
MessageBox.Show(total);
}
else if (i == " ")
{
i = "00";
total = timeArray[0] + i + timeArray[2];
//MessageBox.Show("m-=" + total);
}
//else if (j == "")
//{
// j = "00";
// theTime = timeArray[0] + timeArray[1] + j;
// MessageBox.Show("s-=" + theTime);
//}
}
return total;
}
Why total is 00 :52:04 (for instance) and not 00:52:04 that was supposed to be?
If you'd like to make sure there are no leading or trailing white characters, you could call
string h = timeArray[0].Trim();
And then instead of checking the value against " ", you could compare it to String.Empty or call h.IsNullOrEmpty().
However I'd strongly recommend you to use simpler approach, using a DateTime object.
DateTime timeObject;
DateTime.TryParse(theTime, out timeObject);
and then just work with Hour, Minute and Second properties. This way you get away from custom parsing and make your code more object-oriented, thus easier to read, instead of juggling multiple string objects.
Best way to avoid this is using Trim() when assigning value to total in following two lines:
total = (String.Concat("00",theTime.Trim())).Trim();
.
.
.
total = timeArray[0].trim() + i + timeArray[2].Trim();
Although I was using a MaskedTextBox I didn't define a custom mask so, anywhere (I think) the system assumed that 'theTime' was the type of DateTime.
So, the result of String.Concat("00",theTime) was '00 :32:99', for instance.
I´ve solved it by using the variables h, i and j instead of theTime.
Using a DateTime variable was not appropriated because I want to allow the user to insert NULL values for the hours or for the minutes.
I was wondering if you cloud help me?
I have an array that consist of items and prices and qty.
If the item exist it the array it must update the price and the qty, If it doesn't exits it must be added
Here is my code that i have tried:
if (line.Contains(ItemCode))
{
string[] details = line.Split(new string[] { "|" }, StringSplitOptions.None);
{
for (int i = 0; i < details.Length; i++)
{
if (details[i].Contains(ItemCode))
{
string[] line_details = details[i].Split(',');
string replace = line_details[2].Trim() + "," + line_details[3].Trim();
double NewQty = double.Parse(Qty) + double.Parse(line_details[2]);
double NewPrice = (double.Parse(UnitPrice) * double.Parse(Qty));
double NewUnitPrice = NewPrice + double.Parse(line_details[3]);
string new_replace = NewQty + "," + NewUnitPrice;
line = line.Replace(replace, new_replace);
}
}
}
}
else
{
line = line + "\"Detail\",0," + Qty + "," + (double.Parse(UnitPrice) * double.Parse(Qty)) + "," + InclusivePrice + ",\"" + UnitUsed + "\"," + TaxType + "," + DiscountType + "," + DiscountPercentage + ",\"" + ItemCode + "\",\"" + Description + "\"," + SearchType + "," + "\"\"" + ",\"" + MultiStore + "\"|" + Environment.NewLine;
}
it is not working could you maby assist me on this?
Arrays in C# cannot have entries added to them after being initialised. You're better off using a List<String> instead, where you can add and remove entries from the list. Alternatively consider a Dictionary<Int32, String>, which would let you use the ItemCode as an identifier to make finding a given entry easier.
As a furthur point, instead of storing all your item data in a delimited string, make a new Class for them, with the various details as properties, and then you can use a theoretical Dictionary<Int32, ItemObject> for better clarity.