Merge row dynamically while export using epplus - c#

I want to merge rows in my exported excel using epplus. This code below only works if I just have one same value in one column.
e.g (I merge same value in Col1 row) :
But, if I have another table like this, the code getting error while do merge (I merge same value in Col1 and Col2 row)
Pls, help me fix the code.
void mergeCells(DataTable dt, int startIndex, int totalColumns, ExcelWorksheet ws)
{
if (totalColumns == 0) return;
int i, count = 1;
ArrayList lst = new ArrayList();
lst.Add(ws.Cells[2, 1]);
var ctrl = ws.Cells[startIndex + 1, 1];
for (i = 1; i <= dt.Rows.Count; i++)
{
ExcelRange nextMerge = ws.Cells[i + totalColumns + 1, 1];
if (ctrl.Text == nextMerge.Text)
{
count++;
lst.Add(ws.Cells[i, 1]);
}
else
{
if (count > 1)
{
ws.Cells[i + 1, 1, i + count, 1].Merge = true;
mergeCells(new DataTable(lst.ToString()), startIndex + count, totalColumns, ws);
}
count = 1;
lst.Clear();
ctrl = ws.Cells[i + 2, startIndex];
lst.Add(ws.Cells[i, 1]);
}
}
if (count > 1)
{
ws.Cells[startIndex + 1, 1, startIndex + count, 1].Merge = true;
mergeCells(new DataTable(lst.ToString()), startIndex + count, totalColumns - 1, ws);
}
count = 1;
lst.Clear();
}

I have done like this:
public void WriteDataToSheet(DataTable data)
{
using (ExcelPackage excel = new ExcelPackage())
{
ExcelWorksheet ws = excel.Workbook.Worksheets.Add("Test");
ws.Cells["A1"].LoadFromDataTable(data, true);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
var listObject = data.AsEnumerable()
.Select(x => new
{
Col1 = x.Field<string>("Col1"),
Col2 = x.Field<string>("Col2"),
Col3 = x.Field<string>("Col3")
}).ToList();
var lisa = listObject.GroupBy(x => x.Col1).
Select(x => new
{
Id = x.Key,
Quantity = x.Count(),
secondGroup = x.GroupBy(y => y.Col2)
.Select(y => new
{
ID = y.Key,
secondGroup = y.Count()
})
});
int A = 1, B = 0, C = 1, D = 0;
foreach (var item in lisa)
{
B = A + 1;
A += item.Quantity;
ws.Cells["A" + B + ":A" + A + ""].Merge = true;
ws.Cells["B" + B + ":B" + A + ""].Merge = true;
foreach (var item2 in item.secondGroup)
{
D = C + 1;
C += item2.secondGroup;
ws.Cells["C" + D + ":C" + C + ""].Merge = true;
}
}
// Save merged and modified file to the location
}
}

Related

Bubble sort reversing entire list after 3 inputs

So I'm trying to sort a list of books that have been added to an array alphabetically however, whenever I input the third book, the list flips and sorts the list in unalphabetical order.
If anyone knows why this is, please comment and let me know, my code is below.
The sort to determine if two indexes need to be swapped
private void bookSort()
{
for (int y = 0; y < 20; y++)
{
for (int x = 0; x < bookPTR - 1; x++)
{
if (string.Compare(books[x].GStitle, books[x + 1].GStitle) > 0)
{
bookSwapRoutine(books[x]);
}
}
}
}
The swap itself
private void bookSwapRoutine(Book book, int x = 0)
{
string tempString = books[x].GStitle;
books[x].GStitle = books[x + 1].GStitle;
books[x + 1].GStitle = tempString;
int tempInt = books[x].GSisbn;
books[x].GSisbn = books[x + 1].GSisbn;
books[x + 1].GSisbn = tempInt;
tempString = books[x].GSauthor;
books[x].GSauthor = books[x + 1].GSauthor;
books[x + 1].GSauthor = tempString;
tempString = books[x].GSpublisher;
books[x].GSpublisher = books[x + 1].GSpublisher;
books[x + 1].GSpublisher = tempString;
double tempDouble = books[x].GSprice;
books[x].GSprice = books[x + 1].GSprice;
books[x + 1].GSprice = tempDouble;
tempString = books[x].GSdate;
books[x].GSdate = books[x + 1].GSdate;
books[x + 1].GSdate = tempString;
}
Because of this place. That function call always swap books at zero index and first index because of default parameter x = 0.
bookSwapRoutine(books[x]);
You should call it like.
bookSwapRoutine(books[x], x);
This will swap books[x] and books[x + 1] for you.
If you want just sort your books by GStitle in alphabeticall order you can call.
Array.Sort(books, (x, y) => string.Compare(x.GStitle, y.GStitle, StringComparison.InvariantCulture));
Here all code, with correct bubble sort, if it will help you.
public static void Main()
{
var books = new Book[]
{
new Book() {GStitle = "E"},
new Book() {GStitle = "D"},
new Book() {GStitle = "C"},
new Book() {GStitle = "B"},
new Book() {GStitle = "A"}
};
Console.WriteLine("Before sort.");
foreach (var book in books)
{
Console.WriteLine(book.GStitle);
}
Array.Sort(books, (x, y) => string.Compare(x.GStitle, y.GStitle, StringComparison.InvariantCulture));
//BookSort(books);
Console.WriteLine("After sort.");
foreach (var book in books)
{
Console.WriteLine(book.GStitle);
}
}
public class Book
{
public string GStitle { get; set; }
}
public static void BookSort(Book[] books)
{
for (int y = 0; y < books.Length; y++)
{
for (int x = 0; x < books.Length - 1 - y; x++)
{
if (string.Compare(books[x].GStitle, books[x + 1].GStitle, StringComparison.InvariantCulture) > 0)
{
var temp = books[x];
books[x] = books[x + 1];
books[x + 1] = temp;
}
}
}
}

Formula not identify cell values

I'm generating an excel using the following code in my ASP.Net MVC Application
var fileName = DateTime.Now.ToString("yyyy-MM-dd--hh-mm-ss") + ".xlsx";
var outputDir = ConfigurationManager.AppSettings["ExcelUploadPath"];
// var fileName = "ExcellData.xlsx";
var file = new FileInfo(outputDir + fileName);
var fDate = JsonConvert.DeserializeObject<DateTime>(fromDate);
var tDate = JsonConvert.DeserializeObject<DateTime>(toDate);
using (var package = new OfficeOpenXml.ExcelPackage(file))
{
// add a new worksheet to the empty workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Plan " + DateTime.Now.ToShortDateString());
// --------- Data and styling goes here -------------- //
DataTable dt = planService.GetFlow(fDate, tDate, customerId, ordertypeId, suppliers, items);
if (dt != null)
{
int iCol = 1;
// Add column headings...
for (int i = 9; i < dt.Columns.Count; i++)
{
dt.Columns[i].ColumnName = dt.Columns[i].ColumnName.MultiInsert("/", 1, 3);
}
foreach (DataColumn c in dt.Columns)
{
worksheet.Cells[1, iCol].Value = c.ColumnName;
worksheet.Cells[1, iCol].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[1, iCol].Style.Font.Bold = true;
worksheet.Cells[1, iCol].Style.Fill.BackgroundColor.SetColor(Color.LightGray);
iCol++;
}
for (int j = 0; j < dt.Rows.Count; j++)
{
for (int k = 0; k < dt.Columns.Count; k++)
{
worksheet.Cells[j + 2, k + 1].Value = dt.Rows[j].ItemArray[k].ToString();
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 6)
{
worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Cyan);
}
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 7)
{
worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Magenta);
//worksheet.Cells[j + 2, k + 1].Formula =
if((k+1) > 10){
var addressList = new List<string>();
for (int i = 11; i <= k+1; i++)
{
addressList.Add(worksheet.Cells[((j + 2) -1) , i].Address);
}
var lstAdress = String.Join(",", addressList);
worksheet.Cells[j + 2, k + 1].Formula = "SUM(" + lstAdress + ")";
}
}
if (int.Parse(dt.Rows[j].ItemArray[7].ToString()) == 8)
{
//worksheet.Cells[j + 2, k + 1].Style.Locked = false;
worksheet.Cells[j + 2, k + 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[j + 2, k + 1].Style.Fill.BackgroundColor.SetColor(Color.Gray);
}
}
var colCount = dt.Columns.Count;
// worksheet.Cells[j+2, 8, j+2, colCount- 1].Style.Numberformat.Format = "0.000";
var range = worksheet.Cells[j + 2, 9, j + 2, colCount - 1];
var r = range.ToString();
var decimalValidation = worksheet.DataValidations.AddDecimalValidation(range.ToString());
decimalValidation.ShowErrorMessage = true;
decimalValidation.ErrorStyle = ExcelDataValidationWarningStyle.stop;
decimalValidation.ErrorTitle = "The value you entered is not valid";
decimalValidation.Error = "This cell must be a valid positive number.";
decimalValidation.Operator = ExcelDataValidationOperator.greaterThanOrEqual;
decimalValidation.Formula.Value = 0D;
}
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
worksheet.Column(1).Hidden = true;
worksheet.Column(2).Hidden = true;
worksheet.Column(3).Hidden = true;
worksheet.Column(4).Hidden = true;
worksheet.Column(5).Hidden = true;
worksheet.Column(8).Hidden = true;
worksheet.Column(9).Hidden = true;
worksheet.Column(10).Hidden = true;
worksheet.Protection.IsProtected = true;
// save our new workbook and we are done!
worksheet.Calculate();
package.Save();
return Json(fileName, JsonRequestBehavior.AllowGet);
}
else
{
return Json("NoData", JsonRequestBehavior.AllowGet);
}
}
return Json("", JsonRequestBehavior.AllowGet);
Here I'm setting my formula with comma separated cell names eg:
SUM(A1,A2,A3.. etc)
The excel file is generating correctly. But the problem is the formula calculation is not happen when I open my excel file.
The formula works when I manually change a cell value in Column Type Agreed Flow.
And it can only identify values of manually edited cells.
How can I resolve this?
Formula recalculation is both an Excel and a workbook setting.
You could set it with at the workbook level with
workbook.CalcMode = ExcelCalcMode.Automatic;
If the user has set it to manual though, the formulas won't be recalculated.
If you want to ensure the saved values are correct you can force the calculation by calling
worksheet.Calculate();
You can also calculate the formulas at the workbook or range level, eg :
worksheet.Cells[j + 2, k + 1].Calculate();
or
package.Workbook.Calculate();
This is explained in the documentation. Keep in mind that EPPlus doesn't contain Excel's formula engine. It uses its own engine to parse and calculate formulas. Some things aren't supported
It worked when I change my formula as follows..
var addressList = new List<string>();
for (int i = 11; i <= k+1; i++)
{
addressList.Add(worksheet.Cells[((j + 2) -1) , i].Address);
}
var lstAdress = String.Join("+", addressList);
worksheet.Cells[j + 2, k + 1].Formula = "(" + lstAdress + ")";
I think there is an issue in my excel sheet when I use the SUM function So I write the formula without using it. Then it worked
(A1+B1+C1+D1+ ..... etc)

Code Is Only Writing Last Data To Excel Repeatedly

Instead of writing each element from my foreach loop, my syntax is only writing the last value of the foreach loop to every cell. I am sure this is something that I have overlooked, but what needs to be changed in my syntax so that it will write each element of the foreach loop accordingly on each line?
foreach (var calcs in dictionary)
{
var FileInfo = new FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "WriteDataToExcelThroughCode.xlsx"));
using (ExcelPackage package = new ExcelPackage(FileInfo))
{
ExcelWorksheet ws = package.Workbook.Worksheets["TTest2"];
//ExcelWorksheet ws = package.Workbook.Worksheets[0];
ws.Cells["A24:C36"].Clear();
int z = 0;
int x = 24;
while (z <= numofrows)
{
ws.Cells["A" + x + ":A" + x].Value = calcs.Key;
ws.Cells["B" + x + ":B" + x].Value = dictionary[calcs.Key][0];
ws.Cells["C" + x + ":C" + x].Value = dictionary[calcs.Key][1];
//ws.Cells["D" + x + "D" + x].Value = dictionary[calcs.Key][2];
x = x + 1;
z = z + 1;
}
package.Save();
}
}
EDIT
To better illustrate what my intended results are, is as follows.
Hypothetical calcs contains the following info
James 1 2
Jose 3 4
Bob 5 6
I want the following info to be written to the following cells
A24 = James B24 = 1 C24 = 2
A25 = Jose B25 = 3 C25 = 4
A26 = Bob B26 = 5 C26 = 6
Edit 2
My variable numofrows is set-up like so
int start = Convert.ToInt32(txtstart.Text);
int end = Convert.ToInt32(txtEnd.Text) + 1;
int numofrows = end - start;
int[] abc = Enumerable.Range(start, end-start).ToArray();
foreach (int a in abc)
{
Dictionary<int, int[]> dictionary = new Dictionary<int, int[]>();
dictionary.Add(a, new int[] { 2, 3 });
foreach (var calcs in dictionary)
{
// original code
}
}
private void btnHitIT_Click(object sender, EventArgs e)
{
int start = Convert.ToInt32(Alpha);
int end = Convert.ToInt32(AlphaEnd)+1;
int numofrows = end - start;
int[] angles = Enumerable.Range(start, end - start).ToArray();
foreach (int a in angles)
{
Dictionary<int, int[]> dictionary = new Dictionary<int, int[]>();
dictionary.Add("Jack", new int[] { 2, 3 });
dictionary.Add("James", new int[] { 7, 11 });
dictionary.Add("Jason", new int[] { 14, 21 });
pDrawingArea.Invalidate();
var FileInfo = new FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "WriteDataToExcelThroughCode.xlsx"));
using (ExcelPackage package = new ExcelPackage(FileInfo))
{
ExcelWorksheet ws = package.Workbook.Worksheets["TTest2"];
int x = 24;
foreach (var calcs in dictionary)
{
ws.Cells["A24:C36"].Clear();
for (int z = 0; z <= numofrows; ++z)
{
ws.Cells["A" + x + ":A" + x].Value = calcs.Key;
ws.Cells["B" + x + ":B" + x].Value = dictionary[calcs.Key][0];
ws.Cells["C" + x + ":C" + x].Value = dictionary[calcs.Key][1];
++x;
}
}
package.Save();
}
}
You are defining and incrementing the variable x at the wrong place. You need to define it outside the foreach loop and increment it outside your while loop (but inside the foreach loop).
I have changed your inside while loop to a more appropriate for loop.
Also move the WorkSheet definition outside the foreach loop, since there is no reason to constantly open and close the excel file.
I notice that you search twice for the value in Dictionary given that you already have that value in calcs.Value
var FileInfo = new FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "WriteDataToExcelThroughCode.xlsx"));
using (ExcelPackage package = new ExcelPackage(FileInfo))
{
ExcelWorksheet ws = package.Workbook.Worksheets["TTest2"];
//ExcelWorksheet ws = package.Workbook.Worksheets[0];
int x = 24;
foreach (var calcs in dictionary)
{
ws.Cells["A24:C36"].Clear();
for (int z = 0; z <= numofrows; ++z)
{
ws.Cells["A" + x + ":A" + x].Value = calcs.Key;
ws.Cells["B" + x + ":B" + x].Value = calcs.Value[0];
ws.Cells["C" + x + ":C" + x].Value = calcs.Value[1];
//ws.Cells["D" + x + "D" + x].Value = calcs.Value[2];
++x;
}
package.Save();
}
}

Count Pattern / String Occurrence Per Group using C# in ASP.Net

This is the sample textfile
Line is categorized by date, per line date can be repeated like for example, December 1 and 2 have two entries. Expected Output should be counting the pattern "D;" for example per date
2016-12-01 - 7
2016-12-02 - 9
2016-12-03 - 5
This is what I currently have
using (StreamReader stRead = new StreamReader(FileUpload1.PostedFile.InputStream))
{
while (!stRead.EndOfStream)
{
var readedLine = stRead.ReadLine();
if (!string.IsNullOrWhiteSpace(readedLine))
{
for (int j = 01; j <= 31; j++)
{
int readedLineTime = Convert.ToInt32(readedLine.Substring(09, 02));
if (readedLineTime == j)
{
MatchCollection collection = Regex.Matches(readedLine, #"D;");
countedChars = collection.Count;
textfileOutput += readedLine.Substring(0, 11) + " - " + countedChars + Environment.NewLine;
}
}
}
textfileContent += readedLine + Environment.NewLine;
i++;
}
TextBox1.Text = textfileOutput;
TextBox2.Text = textfileContent;
Label1.Text = i.ToString();
//Label1.Text = this.TextBox1.Text.Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Length.ToString();
// Label2.Text = filename;
}
and this is its current output that is being displayed in multiple line textbox
2016-12-01 - 4
2016-12-01 - 3
2016-12-02 - 4
2016-12-02 - 5
2016-12-03 - 5
Let me know if this works.
Dictionary<string, int> dMyobject = new Dictionary<string, int>();
while (!stRead.EndOfStream)
{
var readedLine = stRead.ReadLine();
if (!string.IsNullOrWhiteSpace(readedLine))
{
int readedLineTime = Convert.ToInt32(readedLine.Substring(09, 02));
string sDate = readedLine.Substring(0, 11);
MatchCollection collection = Regex.Matches(readedLine, #"D;");
countedChars = collection.Count;
if (!dMyobject.Keys.Contains(sDate))
{
dMyobject.Add(sDate, collection.Count);
}
else
{
dMyobject[sDate] = dMyobject[sDate] + collection.Count;
}
}
textfileContent += readedLine + Environment.NewLine;
i++;
}
You will need to push these values in some collection. So that you can check it.
Later, for using these values for printing or anything, use following
foreach (var item in dMyobject)
{
Console.WriteLine(item.Key + " " + item.Value);
}
string line = "";
Dictionary<string, int> list = new Dictionary<string, int>();
int count;
if (File.Exists(fileName) == true)
{
StreamReader objReader;
objReader = new StreamReader(fileName);
StreamWriter file = new StreamWriter(OutputfileName");
do
{
line = objReader.ReadLine();
string temp = line.Substring(0, 10);
if (!list.ContainsKey(temp))
{
MatchCollection collection = Regex.Matches(line, #"D;");
count = collection.Count;
list.Add(temp, count);
}
else
{
MatchCollection collection = Regex.Matches(line, #"D;");
count = collection.Count;
var val = list[temp];
list[temp] = count + val;
}
} while (objReader.Peek() != -1);
foreach (var j in list)
{
file.WriteLine(j.Key + " - " + j.Value+"\n");
}
file.Close();
}

how to code for checkbox to get pattern output explain below

I am working on c# application and i want to accomplish following task:
I have 12 check boxes for 12 items and user can check any of the check boxes.
if check boxes 3,4,5,6,8,10,11,12 have been checked, I would like to display following output.
You have selected items 3-6,8,10-12.
Rules:
When consecutive number group count is 3 or more than 3,Show grouping like 3-6
else show individual number. 8
Firstly I suggest you to append value of all the checkbox in string like you have shown.
Function Calling :
string data = "3,5,6,7,8,10,12";
string res = GetResultString(data);
Functions :
string GetResultString(string data)
{
string[] arrData = data.Split(',').ToArray();
List<int> lstData = new List<int>();
foreach (string item in arrData)
{
lstData.Add(Convert.ToInt16(item));
}
lstData.Sort();
string finalStr = string.Empty;
if (lstData.Count > 0)
{
int start = lstData[0];
int end = start;
finalStr = string.Empty;
for (int index = 1; index < lstData.Count; index++)
{
if (end + 1 == lstData[index])
{
end = lstData[index];
}
else
{
finalStr += appendResult(start, end);
start = -1;
}
if (start == -1)
{
start = lstData[index];
end = lstData[index];
}
}
finalStr += appendResult(start, end);
}
finalStr = finalStr.Trim(',');
return finalStr;
}
string appendResult(int start,int end)
{
string res = string.Empty;
if (end - start > 1)
{
res += start + "-" + end.ToString() + ",";
start = -1;
}
else
{
while (start <= end)
{
res += start.ToString() + ",";
start++;
}
}
return res;
}
Hope this will done your job,
try this .. it will work i tested it
I have not created checkboxes so it is up to you to check which checkbox is selected get the string like from the selected checkboxes 3,4,5,6,8,10,11,12
string str1 = "3,4,5,6,8,10,11,12";
string[] strArr = str1.Split(',');
List<string> strFinal = new List<string>();
int[] myInts = Array.ConvertAll(strArr, s => int.Parse(s));
int arrLn = myInts.Length;
Array.Sort(myInts);
int intPrevVal = myInts[0];
int intPrevDiff = myInts[0];
int seriesCount = 1;
strFinal.Add(Convert.ToString(myInts[0]));
for (int j = 1; j < arrLn; j++)
{
int intCurr = myInts[j];
if (intCurr - intPrevVal == 1)
{
seriesCount++;
}
else
{
if (seriesCount >= 3)
{
strFinal[strFinal.Count - 1] = strFinal[strFinal.Count - 1] + "-" + intPrevVal;
seriesCount = 1;
}
else if (seriesCount == 2)
{
strFinal.Add(Convert.ToString(myInts[j - 1]));
seriesCount = 1;
//strFinal.Add(Convert.ToString(myInts[j]));
}
strFinal.Add(Convert.ToString(myInts[j]));
}
intPrevVal = intCurr;
}
if (seriesCount >= 3)
{
strFinal[strFinal.Count - 1] = strFinal[strFinal.Count - 1] + "-" + myInts[arrLn - 1];
}
else if (seriesCount == 2)
{
strFinal.Add(Convert.ToString(myInts[arrLn - 1]));
}
string FinalAns = string.Join(",", strFinal.ToArray());
Response.Write(FinalAns);
I suppose you did your checkbox with array (new...) if not do it maunally...
int min=13;
int max=0;
string s = "";
for (int i = 0; i<12; i++)
{
if (cb[i].checked && i<min)
min = i;
else if (cb[i].checked == false)
if (min != 13)
{
max = i-1;
s = s + min.ToString() + "-" + max.ToString() + " ";
min = 13;
}
}
if (cb[11].checked) s = s + min.ToString() + "-12"; // for case the last one is checked
// s contains your data
(I didn't check it but I think it need to be something like this.)
try this
var data = new List<int> { 3, 4, 5, 6, 8, 10, 11, 12 };
// data.Sort();
var groups = new List<string>();
var startIndex = 0;
for (var i = 1; i < data.Count; i++)
{
if (data[i - 1] == data[i] - 1)
{
continue;
}
groups.Add(startIndex == i - 1
? data[startIndex].ToString()
: data[startIndex] + "-" + data[i - 1] );
startIndex = i;
}
groups.Add(startIndex == data.Count - 1
? data[startIndex].ToString()
: data[startIndex] + "-" + data[data.Count - 1]);
var result = string.Join(",", groups);
version 2
[Fact]
public void Test()
{
var data = new List<int> { 3, 4, 5, 7, 8, 10, 11, 12 };
// data.Sort();
var groups = new List<string>();
var startIndex = 0;
for (var i = 1; i < data.Count; i++)
{
if (data[i - 1] == data[i] - 1)
{
continue;
}
AddToGroups(groups, startIndex, i, data);
startIndex = i;
}
AddToGroups(groups, startIndex, data.Count, data);
var result = string.Join(",", groups);
Assert.Equal("3-5,7,8,10-12", result);
}
private static void AddToGroups(List<string> groups, int startIndex, int actualIndex, List<int> data)
{
switch (actualIndex - startIndex)
{
case 1:
groups.Add(data[startIndex].ToString());
break;
case 2:
groups.Add(data[startIndex].ToString());
groups.Add(data[startIndex + 1].ToString());
break;
default:
groups.Add(data[startIndex] + "-" + data[actualIndex - 1]);
break;
}
}
You might have got the solution,but all the above solutions use string for appending data..You could use StringBuilder for optimized performance.
List<int> selectedCB = new List<int>() { 3, 4, 6, 7, 8, 9, 11, 12 };
string output = GetFormattedOutput(selectedCB);
The code for formatting data..
private string GetFormattedOutput(List<int> selectedCB)
{
// Can be changed if you want to increase
// groupby range
int rangeBy = 3;
int diffBy = 1;
int prevValue = 0;
List<int> tempList = new List<int>();
StringBuilder formattedOutput = new StringBuilder();
foreach (int currentValue in selectedCB)
{
var diff = currentValue - prevValue;
if(tempList.Count != 0 && diff > diffBy)
{
// Add the value in templist to formatted output
// If three are more numbers are in range
// Add the first and last
if (tempList.Count >= rangeBy)
{
formattedOutput.Append(tempList[0].ToString() + "-" +
tempList[tempList.Count - 1].ToString()+",");
}
else
{
AppendText(formattedOutput, tempList);
}
tempList.Clear();
}
tempList.Add(currentValue);
prevValue = currentValue;
}
if (tempList.Count != 0)
{
AppendText(formattedOutput, tempList);
}
formattedOutput.Remove(formattedOutput.Length - 1, 1);
return formattedOutput.ToString();
}
// To append the numbers in the list
string AppendText(StringBuilder output, List<int> tempList)
{
foreach (var temp in tempList)
{
output.Append(temp.ToString() + ",");
}
return output.ToString();
}

Categories

Resources