Reorder HTML Table Cells - c#

I have a ASP.NET page that displays a table in which every cell represents an object. This object is generated by code behind in C# sent to the page via JSON, and a Javascript function reads every object and makes a HTML cell, displaying the properties of the object inside.
I have a defined row and column quantity for each case. For example, if my total of objects is 20, the number of columns would be 4 and the number of rows would be 5.
Each object has a numeric identificator, from 1 to 20 as in the example. The objects are filled on the table from left to right, row by row, resulting in a grid like this:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 18 20
The object has the following structure:
public class AreaData
{
public string AreaId;
public int Rows;
public int Columns;
public int TotalCells;
public bool Orientation;
public List Cells;
}
public class CellData
{
public string CellName;
public int CellNumber;
}
The basic outline of the Javascript function that makes the table is:
function ReturnGrid(object, settings) {
var objId = settings["objId"];
var objName = settings["objName"];
if ((settings["columns"] * settings["rows"]) == object[objName].length) {
var table = CreateFullElement("table", "id", "Table" + object[objId], "class", settings["styles"]["table_css"], "style", settings["styles"]["table_style"]);
var tableBody = document.createElement("tbody");
var index = 0;
for (var j = 0; j < settings["rows"]; j++) {
var tableRow = document.createElement("tr");
for (var i = 0; i < settings["columns"]; i++) {
var tableCell = CreateFullElement("td", "id", "CellName-" + object[objName][index]["CellName"], "title", object[objName][index]["CellName"], "style", settings["styles"]["td_style"]);
object[objName][index]["ServiceTag"] = object[objName][index]["ServiceTag"].toUpperCase();
var cellContainer;
cellContainer = CreateFullElement("div", "id", object[objName][index]["CellName"], "class", settings["classes"]["cellContent_css"], "style", cellContent_style + "background-color:" + settings["deviceStatusColors"][object[objName][index]["DeviceStatus"]]+";");
var cellNumText = document.createTextNode(object[objName][index]["CellNumber"]);
cellNumContainer = CreateFullElement("div", "class", settings["classes"]["cellNumContent_css"], "style", cellNumContent_style + textcolor_Style);
cellNumContainer.appendChild(cellNumText);
tableCell.appendChild(cellContainer);
tableRow.appendChild(tableCell);
index++;
}
tableBody.appendChild(tableRow);
}
table.appendChild(tableBody);
return table;
}
else {
console.log("The values of rows and columns does not match with the length of the object");
}
}
However, I want to rearrange that grid based on two conditions:
1) Fill the grid up to down
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
2)If required fill the grid as a mirror.
16 11 6 1
17 12 7 2
18 13 8 3
19 14 9 4
20 15 10 5
Is there a way to implement this functionality with Javascript, an already made function with Jquery? Or do I have to sort the object before stringify it to JSON?
Thanks in advance

Related

How to access the string array elements for search?

I have a text file that include of numbers and I save it in a string array.
one line of my text file is this:
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21
every line save in one of indexes of string array.
now how can i access array elements as int type and search and calculate in all of array?
this is my array:
string [] lines = File.ReadAllLines(txtPath.Text);
for example I want to return indexes of array that include number'14' in all of array .
This is the easiest and clearest way to solve it. I commented so you can better understand what happens in the entire program.
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
int integerNumber;
// checking if the string lineElements[j] is a number (because there also this case 114:275:5)
if (int.TryParse(lineElements[j], out integerNumber))
{
// if it is we check if the number is 14, in that case we add that index to the indexes list
if (integerNumber == 14)
{
indexes.Add(j);
}
}
}
}
// Printing out lines and indexes:
foreach (int key in dict.Keys)
{
Console.WriteLine(string.Format("LINE KEY: {0}", key));
foreach (int index in dict[key])
{
Console.WriteLine(string.Format("INDEX ELEMENT: {0}", index));
}
Console.WriteLine("------------------");
}
Console.ReadLine();
}
}
UPDATE 1:
As you requested:
special thanks for your clear answering.if i want to do search for all of my array elements what can i do? it means instead of only
number'14' i want to print indexes of all numbers that appear in
indexes
If you want to print all the indexes you should Console.WriteLine(j), that is the index of the inner for cycle, instead of checking the number value if (integerNumber == 14).
So, this is the program:
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
// printing all indexes of the current line
Console.WriteLine(string.Format("Element index: {0}", j));
}
}
Console.ReadLine();
}
}
UPDATE 2:
As you requested:
if i want to search my line till first " : " apper and then search next line, what can i do?
You need to break the for cycle when you are on the element with :
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
// I'm saving the content of lineElements[j] as a string
string element = lineElements[j];
// I'm checking if the element saved as string contains the string ":"
if (element.Contains(":"))
{
// If it does, I'm breaking the cycle, and I'll continue with the next line
break;
}
int integerNumber;
// checking if the string lineElements[j] is a number (because there also this case 114:275:5)
if (int.TryParse(lineElements[j], out integerNumber))
{
// if it is we check if the number is 14, in that case we add that index to the indexes list
if (integerNumber == 14)
{
indexes.Add(j);
}
}
}
}
// Printing out lines and indexes:
foreach (int key in dict.Keys)
{
Console.WriteLine(string.Format("LINE KEY: {0}", key));
foreach (int index in dict[key])
{
Console.WriteLine(string.Format("INDEX ELEMENT: {0}", index));
}
Console.WriteLine("------------------");
}
Console.ReadLine();
}
}
As you can see, if you run this piece of code and compare it with the first version, in output you'll get only the index of the first 14 occurrence, because the second one is after the string with :.
First you must get all conttent of file in the string array format:
public string[] readAllInFile(string filepath){
var lines = File.ReadAllLines(path);
var fileContent = string.Join(' ',lines);//join all lines of file content in one variable
return fileContent.Split(' ');//each word(in your case each number) in one index of array
}
and in usage time you can do like this:
var MyFileContent = readAllInFile(txtPath.Text);
int x= Convert.ToInt32(MyFileContent[2]);
IEnumerable<int> numbers = MyFileContent.Select(m=> int.Parse(m);)
var sumeOf = numbers.sum();
you can use linq to have more tools on collections.
var linesAsInts = lines.Select(x => x.Split(' ').Select(int.Parse));
var filteredLines = linesAsInts.Where(x => x.Contains(14));
// define value delimiters.
var splitChars = new char[] { ' ', ':' };
// read lines and parse into enumerable of enumerable of ints.
var lines = File.ReadAllLines(txtPath.Text)
.Select(x => x.Split(splitChars)
.Select(int.Parse));
// search in array.
var occurences = lines
.Select((line,lineIndex) => line
.Select((integer, integerIndex) => new { integer, integerIndex })
.Where(x => x.integer == 10)
.Select(x => x.integerIndex));
// calculate all of array.
var total = lines.Sum(line => line.Sum());

Keep the relative order of items of same value when keep sorting a list

Suppose you need to keep a changing list, which may contain items of duplicate values, sorted. For example you had [99, 99, 90, 89], but the 4th item's value has changed to 91. You would want it to be [99, 99, 91, 90], but you would not want the order of the first and the second item to change.
I used the Sort() method but it seems that it may change the order of the first and the second items of the example above. Is there any way to prevent it and keep the relative order of items which have the same values?
In case if you cannot think of why this would be necessary, suppose a progress list. The items in the list are updated every second. When the items are sorted by the progress, you would want the items of the same progress keep changing their relative positions.
I have created a sample code to test this. The goal would be reaching Debug.WriteLine("No change");.
public void Start()
{
var list = new List<Item>();
var ran = new Random();
const int nItems = 30;
for (int i = 0; i < nItems; i++)
{
var name = "Item " + (list.Count + 1);
var item = new Item(name, ran.Next(0, 10));
list.Add(item);
}
var sorter = new ItemComparer();
var snapshot = new Item[nItems];
for (int nSort = 0; nSort < 10000; nSort++)
{
list.CopyTo(snapshot);
list.Sort(sorter);
if (nSort == 0)
{
//Sorted for the first time, so the snapshot is invalid.
continue;
}
for (int pos = 0; pos < nItems; pos++)
{
if (snapshot[pos] != list[pos])
{
Debug.WriteLine($"Order changed at position {pos} after {nSort} sorts.");
PrintChangedLocation(list, snapshot, pos);
return;
}
}
}
Debug.WriteLine("No change");
}
private static void PrintChangedLocation(List<Item> list, Item[] snapshot, int changedLocation)
{
Debug.WriteLine($"Before\t\t\tAfter");
for (int pos = 0; pos < list.Count; pos++)
{
var before = snapshot[pos];
var after = list[pos];
Debug.Write($"{before.Name} = {before.Progress}");
Debug.Write($"\t\t{after.Name} = {after.Progress}");
if (pos == changedLocation)
{
Debug.Write(" <----");
}
Debug.WriteLine("");
}
}
class Item
{
public string Name;
public float Progress;
public Item(string name, float progress)
{
Name = name;
Progress = progress;
}
}
class ItemComparer : IComparer<Item>
{
int Direction = -1;
public int Compare(Item x, Item y)
{
return Direction * (int)(x.Progress - y.Progress);
}
}
Sample output:
Order changed at position 12 after 1 sorts.
Before After
Item 7 = 9 Item 7 = 9
Item 24 = 9 Item 24 = 9
Item 30 = 8 Item 30 = 8
Item 4 = 8 Item 4 = 8
Item 19 = 8 Item 19 = 8
Item 27 = 7 Item 27 = 7
Item 5 = 7 Item 5 = 7
Item 25 = 7 Item 25 = 7
Item 20 = 7 Item 20 = 7
Item 26 = 6 Item 26 = 6
Item 14 = 6 Item 14 = 6
Item 1 = 6 Item 1 = 6
Item 28 = 5 Item 2 = 5 <----
Item 2 = 5 Item 12 = 5
Item 12 = 5 Item 28 = 5
Item 11 = 4 Item 11 = 4
Item 6 = 4 Item 6 = 4
Item 13 = 3 Item 13 = 3
Item 3 = 3 Item 3 = 3
Item 21 = 3 Item 21 = 3
Item 10 = 3 Item 10 = 3
Item 18 = 3 Item 18 = 3
Item 22 = 2 Item 22 = 2
Item 29 = 2 Item 29 = 2
Item 23 = 1 Item 23 = 1
Item 8 = 1 Item 8 = 1
Item 17 = 1 Item 17 = 1
Item 16 = 0 Item 9 = 0
Item 9 = 0 Item 16 = 0
Item 15 = 0 Item 15 = 0
One option to consider would be changing:
list.Sort(sorter);
to:
list = list
.Select((item, index) => new { item, index})
.OrderBy(z => z.item, sorter)
.ThenBy(z => z.index)
.Select(z => z.item)
.ToList();
This allows you sort by your comparer, then by its position in the List - thus keeping the relative order.

Check and count values of a table column and show them in a pie chart using SQLite database in C#.NET

I am trying to draw a simple pie chart where data will come from a SQLite database. I need to check a column of a table whether it has value 2 or 1 or 0. I have written 3 functions to check and count them. Table name is banana and column name is status. The table is like following
Id B M status
1 10 101 2
2 11 102 2
3 11 103 0
4 12 104 1
5 13 105 1
6 13 105 0
7 14 106 1
8 14 106 2
The functions are
public double countA()
{
return GetDoubleEntity("SELECT COUNT(*) FROM banana WHERE banana.status = '2';");
}
public double countB()
{
return GetDoubleEntity("SELECT COUNT(*) FROM banana WHERE banana.status = '1';");
}
public double countC()
{
return GetDoubleEntity("SELECT COUNT(*) FROM banana WHERE banana.status = '0';");
}
Then I have written following codes to draw the pie chart
double Total, APercentage, BPercentage, CPercentage;
Total= countA() + countB() + countC();
APercentage= (countA() * 100) / Total;
BPercentage= (countB() * 100) / Total;
CPercentage= (countC() * 100) / Total;
//Take legend
string[] xAxis = { "A", "B", "C" };
//Take Percentage Values
double[] PiePercentage = { APercentage, BPercentage, CPercentage};
Chart.Series[0].Label = "#PERCENT";
Chart.Series[0].LegendText = "#AXISLABEL";
Chart.Series[0].Points.DataBindXY(xAxis, PiePercentage);
Chart.Series[0].Points[0].Color = Color.Green;
Chart.Series[0].Points[1].Color = Color.Red;
Chart.Series[0].Points[2].Color = Color.Yellow;
But, it is not showing results. Could anyone give me any hints what is wrong with it ? Is it problem with SQL queries or chart functions which are creating the problems ?

Check if string contains a successive pair of numbers

I have one list. I want check if list[i] contains string "6 1". But this code thinks 6 13 24 31 35 contains "6 1". Its false.
6 13 24 31 35
1 2 3 6 1
stringCheck = "6 1";
List<string> list = new List<string>();
list.Add("6 13 24 31 35");
list.Add("1 2 3 6 1");
for (int i=0; i<list.Count; i++)
{
if (list[i].Contains(stringCheck)
{
// its return me two contains, but in list i have one
}
}
But this code thinks 6 13 24 31 35 contains "6 1". Its false. […]
List<string> list = new List<string>();
list.Add("6 13 24 31 35");
list.Add("1 2 3 6 1");
No, it's true because you are dealing with sequences of characters, not sequences of numbers here, so your numbers get treated as characters.
If you really are working with numbers, why not reflect that in the choice of data type chosen for your list?:
// using System.Linq;
var xss = new int[][]
{
new int[] { 6, 13, 24, 31, 35 },
new int[] { 1, 2, 3, 6, 1 }
};
foreach (int[] xs in xss)
{
if (xs.Where((_, i) => i < xs.Length - 1 && xs[i] == 6 && xs[i + 1] == 1).Any())
{
// list contains a 6, followed by a 1
}
}
or if you prefer a more procedural approach:
foreach (int[] xs in xss)
{
int i = Array.IndexOf(xs, 6);
if (i >= 0)
{
int j = Array.IndexOf(xs, 1, i);
if (i + 1 == j)
{
// list contains a 6, followed by a 1
}
}
}
See also:
Finding a subsequence in longer sequence
Find sequence in IEnumerable<T> using Linq

Merge 2 DataTables

I have 2 Datatable with these fields:
DataTable1
Hour - Value1
0 - 34
1 - 22
2 - NULL
3 - 12
..
..
23 - 10
DataTable2
Hour - Value1
0 - NULL
1 - 22
2 - 35
3 - 11
..
..
23 - NULL
I need to populate an unique DataTable that has the same "Hour" fields (the hours of the day) and for the values has to get the values from DataTable1 if is not null. If the values in Datatable1 is null, I have to take the correspondet values from DataTable2.
If also the value from DataTable2 is null, I have to log the error.
For my example, I need to get:
DataTableResult
Hour - Value1
0 - 34
1 - 22
2 - 35
3 - 12
..
..
23 - 10
How can I get this?
This is question follows a simple conditional logic you would need to process each element in a foreach statement.
You want to process this so every time an element in a row has null.
You go to that row in datatable 2 and check if that has a value if so this becomes the new value in
datatable 1.
If this does not then throw an error.
I have provided this link how to compare but really you don't need this as all you are doing is testing for null in a field in a row.
Using Linq to objects and assuming dataTable1 and dataTable2 have the same columns:
var hoursMap1 = dataTable1.Rows.Cast<DataRow>().ToDictionary(row => row[0]);
var hoursMap2 = dataTable2.Rows.Cast<DataRow>().ToDictionary(row => row[0]);
var resultTable = new DataTable();
// Clone the column from table 1
for (int i = 0; i < dataTable1.Columns.Count; i++)
{
var column = dataTable1.Columns[i];
resultTable.Columns.Add(column.ColumnName, column.ColumnType);
}
foreach (var entry in hoursMap1)
{
int hours = entry.Key;
DataRow row1 = entry.Value;
DataRow row2 = null;
if (!hoursMap2.TryGetValue(hours, out row2))
{
// Hours in table 1 but not table 2, handle error
}
var fields = new object[resultTable.Columns.Count];
int fieldIndex = 0;
fields[fieldIndex++] = hours;
for (int i = 1; i < row1.ItemsArray.Length; i++)
{
var field1 = row1.ItemsArray[i];
var field2 = row2.ItemsArray[i];
var newField = field1 ?? field2;
if (newField == null)
{
// Field neither in table 1 or table 2, handle error
}
fields[fieldIndex++] = newField;
}
resultTable.Rows.Add(fields);
}

Categories

Resources