I have a table with 2 rows with each 3 columns in it and an Array with 5 values. These values should be displayed successively in the 3 columns, e.g.
indexPath.row 0: Array[0] | Array[1] | Array[2]
indexPath.row 1: Array[3] | Array[4] |
I want to create some coding, which puts my values (it doesn't care how much e.g. 5,6,7,...,20,21 in the format of 3 columns in rows) the rows are calculated at the size of the array with the values.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSMutableArray *values = [... getValues];
int no=0;
if (values) {
no=(values.count+1)/3;
}
else{
no=0;
}
return no;
}
My current problem is, I don't get the 5 values distributed in the columns.
I'm struggeling around with the calculation, these won't fit with the index of the array ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//order values in 3 columns and 2 rows (currently)...
}
BR,
mybecks
Suppose COLS is the number of columss, and V is the number of values, where M is the matrix, and Vector is the values vector:
for i = 0 to V-1:
M[i div COLS][i mod COLS] = Vector[i]
Found a solution.
NSInteger count = numberOfValues;
NSInteger start = indexPath.row * 3;
NSInteger end = MIN(start + 3, count);
for(int i = start; i < end; i++)
{
if(i%3 == 0){//left}
if(i%3 == 1){//center}
if(i%3 == 2){//right}
}
Related
Let's say I have a column of numbers:
1
2
3
4
5
6
7
8
Is there a formula that can calculate sum of numbers starting from n-th row and adding to the sum k numbers, for example start from 4th row and add 3 numbers down the row, i.e. PartialSum(4, 3) would be 4 + 5 + 6 = 15
BTW I can't use App Script as now it has some type of error Error code RESOURCE_EXHAUSTED. and in general I have had issue of stabile work with App Script before too.
As Tanaike mentioned, the error code when using Google Apps Script was just a temporary bug that seems to be solved at this moment.
Now, I can think of 2 possible solutions for this using custom functions:
Solution 1
If your data follows a specific numeric order one by one just like the example provided in the post, you may want to consider using the following code:
function PartialSum(n, k) {
let sum = n;
for(let i=1; i<k; i++)
{
sum = sum + n + i;
}
return sum;
}
Solution 2
If your data does not follow any particular order and you just want to sum a specific number of rows that follow the row you select, then you can use:
function PartialSum(n, k) {
let ss = SpreadsheetApp.getActiveSheet();
let r = ss.getRange(n, 1); // Set column 1 as default (change it as needed)
let sum = n;
for(let i=1; i<k; i++)
{
let val = ss.getRange(n + i, 1).getValue();
sum = sum + val;
}
return sum;
}
Result:
References:
Custom Functions in Google Sheets
Formula:
= SUM( OFFSEET( initialCellName, 0, 0, numberOfElementsInColumn, 0) )
Example add 7 elements starting from A5 cell:
= SUM( OFFSEET( A5, 0, 0, 7, 0) )
I'm wondering how to find the horizontally and vertically adjacent or surrounding cells/IndexPaths to a specific (red) cell in UICollectionView.
The red cell may be at any position.
I can find the red cell's indexPath, wether it is at any position.
I am attaching this Image file to clear my question more.
Any help or idea will be greatly appreciated.
Algorithm
Assuming :
There are four cells in each row.
Calculation :
int rowCount = 4 // Total no of cells in a row. As you already described it.
int lastRow = totalCell / rowCount // last row number.
int colNo = index % rowCount // column Number i.e. this index is at which column
int rowNo = index / rowCount // this index is at which row
Algo
1. if `colNo == 0` // cell is the left most.
if `rowNo == 0` // index of first row
adjacent = index + 1, index + rowCount
else if `rowNo == lastRow` // index of last row
adjacent = index + 1, index - rowCount
else
adjacent = index + 1, index - rowCount
2. if `colNo == 1` // cell is the second in its row .
if `rowNo == 0` // index is at first row
adjacent = index - 1, index + 1, index + rowCount
else if `rowNo == lastRow` // index is at last row
adjacent = index - 1 ,index + 1, index - rowCount
else
adjacent = index + 1, index - rowCount, index - 1
3. if `colNo == 2` // cell is the third in row.
if `rowNo == 0` // index of first row
adjacent = index - 1, index + 1, index + rowCount
else if `rowNo == lastRow` // index of last row
adjacent = index - 1, index + 1, index - rowCount
else
adjacent = index + 1, index - rowCount, index - 1
4. if `colNo == 3` // cell is the left most.
if `rowNo == 0` // index of first row
adjacent = index - 1, index + rowCount
else if `rowNo == lastRow` // index of last row
adjacent = index - 1, index - rowCount
else
adjacent = index - 1, index - rowCount
OK If they are all the same size say 100x100 then get the cell you selected and
Ask the collectionView for the CGRect of the cell
Find the center.
Then ask the collectionView for cells at points, x - 100, x + 100, y - 100, y + 100.
Then see which are not nil?
my solution does not take any spacing or different cell sizes into account but to give you an idea of how it could work:
private func selectCellAndAdjacentCellsAtIndexPath(_ indexPath: IndexPath) {
if let cell = collectionView?.cellForItem(at: indexPath) {
var cellsToSelect: [UICollectionViewCell] = [cell]
// get adjacent cells
// top
if let topIndexPath = collectionView?.indexPathForItem(at: CGPoint(x: cell.center.x, y: cell.center.y - cell.frame.height)), let topCell = collectionView?.cellForItem(at: topIndexPath) {
cellsToSelect.append(topCell)
}
// left
if let leftIndexPath = collectionView?.indexPathForItem(at: CGPoint(x: cell.center.x - cell.frame.width, y: cell.center.y)), let leftCell = collectionView?.cellForItem(at: leftIndexPath) {
cellsToSelect.append(leftCell)
}
// bottom
if let bottomIndexPath = collectionView?.indexPathForItem(at: CGPoint(x: cell.center.x, y: cell.center.y + cell.frame.height)), let bottomCell = collectionView?.cellForItem(at: bottomIndexPath) {
cellsToSelect.append(bottomCell)
}
// right
if let rightIndexPath = collectionView?.indexPathForItem(at: CGPoint(x: cell.center.x + cell.frame.width, y: cell.center.y)), let rightCell = collectionView?.cellForItem(at: rightIndexPath) {
cellsToSelect.append(rightCell)
}
// select cells
for cellToSelect in cellsToSelect {
cellToSelect.backgroundColor = UIColor.lightGray
}
}
}
So I have this function here that runs through T2:T:
=IF($D$29<$N2,"", AVERAGE(INDIRECT("P"&IF($N2<11, 2,$N2-5)&":P"&$N2+5)))
Column P is a list of numbers starting at row 2. Column N is an index(goes up by 1 each row) which starts at row 2 and ends where P ends + 14, and D29 is just a number. In my current situation P ends at row 11 and N ends at row 25. And I'm trying to change it into an array formula so that when I add new rows it updates automatically. So after changing it I got this:
=ARRAYFORMULA(IF($D$29<$N2:N,"", AVERAGE(INDIRECT("P"&IF($N2:N<11, 2,$N2:N-5)&":P"&$N2:N+5))))
However, it is not functioning properly. It still occupies the same amount of rows, but each row is the same value. The value of the first row originally. How can I fix this problem? Thanks!
The problem here is that ARRAYFORMULA doesn't work with AVERAGE.
But you could always use javascript.
Open up the script editor and paste in this code.
function avg(nums, d) {
var r = [],
i, j, start, end, avg, count;
for(i = 0; i < nums.length; i++) {
if(d <= i) r.push([""]);
else {
if(i < 10) start = 0;
else start = i - 5;
end = i + 4;
avg = 0, count = 0;
for(j = start; j <= end; j++) {
if(nums[j]) {
avg += nums[j][0];
count++;
}
}
r.push([avg / count]);
}
}
return r;
}
Save it, go back to your spreadsheet and put this formula in any cell =avg(P2:P11, D29)
I have a dynamic array. I need to display tableview as following scenario...
In the First cell i need to display 1 item.
In the second cell i need to display 2 items.
In the third cell i need to display 3 items.
In the forth cell i need to display 1 item.
In the fifth cell i need to display 2 items.
In the sixth cell i need to display 3 items.
and so on...
Could any one please suggest how to return no of rows in a section.
Try this :
int noOfRow = total/2 + ceil((total % 3)/3.0);
Simple logic for this is:
NoOfRows = TotalCount / 2
For e.g.:
If last value is 6 then, total no of rows are (6 / 2) = 3
If last value is 12 then, total no of rows are (12 / 2) = 6
You have to think logical that's it.
Hope this helps.
A faster method might be:
Notice in the divide by 2 method, most numbers work. The ones don't work are:
2, 4, 8, 10... basically, even numbers that aren't divisible by 6.
So we can come up with something like:
int count = array.count;
if (count % 2 == 0 && count % 6 != 0) {
count + 2;
}
int rows = ceilf(count / 2);
Or we can write a for loop:
int counter = array.size;
int rows = 0;
int dec = 1;
while (counter > 0) {
rows++;
counter - dec;
dec = dec % 3 + 1;
}
The for loop is of course, slower.
I have to create an array of pointers for rows and columns initially all pointing to null.
The address of the newly created row/column headers are to be inserted into the arrays.
In the result I see that the addresses are repeated in the row and column arrays.
Problem: the addresses are repeated in the row and column arrays.
I have to mention that I did not use delete (for deallocating the memory yet, because i am confused where to include it whether inside the function or outside).
I also see that no rowheader is created for the token 2x3y3.
First I created an array of pointers
//allocating row and column pointers, m is number of rows and n is number of columns
- node **rArr = new node*[m+1];
- node **cArr = new node*[n+1];
void create_array_with_nullp(){
for(int i=0; i<=m;i++){
rArr[i]=NULL;
std::cout<<"row array contents"<<rArr[i]<<'\n';
}
for(int i=0; i<=n;i++){
cArr[i]=NULL;
std::cout<<"col array contents"<<cArr[i]<<'\n';
}
}
Then I am creating rowheaders or colheaders for the tokens if not already created through the following function:
void create_n_link_new_node(int a, int b){
if(a >m || b>n || a<0 || b<0){
return;
}
node * colptr = cArr[b];
node * rowptr = rArr[a];
if (rowptr==NULL){
node * new_rowheader = new node;
new_rowheader->coefficient = NULL;
new_rowheader->row = a;
new_rowheader->column = -1;
new_rowheader->rowLink = new_rowheader;
new_rowheader->colLink = new_rowheader;
rArr[a] = new_rowheader;
std::cout<<"new row header created"<<'\n';
std::cout<< "coefficient = "<<new_rowheader->coefficient<<'\n';
std::cout<< "row = "<<new_rowheader->row<<'\n';
std::cout<< "column = "<<new_rowheader->column<<'\n';
std::cout<< "rowLink = "<<new_rowheader->rowLink<<'\n';
std::cout<< "colLink = "<<new_rowheader->colLink<<'\n';
}
if(colptr == NULL){
node * new_colheader = new node;
new_colheader->coefficient = NULL;
new_colheader->row = -1;
new_colheader->column = b;
new_colheader->rowLink = new_colheader;
new_colheader->colLink = new_colheader;
cArr[b] = new_colheader;
std::cout<<"new column header created"<<'\n';
std::cout<< "coefficient = "<<new_colheader->coefficient<<'\n';
std::cout<< "row = "<<new_colheader->row<<'\n';
std::cout<< "column = "<<new_colheader->column<<'\n';
std::cout<< "rowLink = "<<new_colheader->rowLink<<'\n';
std::cout<< "colLink = "<<new_colheader->colLink<<'\n';
}
}
The Result is:
THE RESULT:
token==5x4y2
coefficient=5
row= 4
col = 2
new row header created
coefficient = 0
row = 4
column = -1
rowLink = 0x100103c10
colLink = 0x100103c10
new column header created
coefficient = 0
row = -1
column = 2
rowLink = 0x100103c30
colLink = 0x100103c30
token==8x4y
coefficient=8
row= 4
col = 1
new column header created
coefficient = 0
row = -1
column = 1
rowLink = 0x100103c50
colLink = 0x100103c50
token==2x3y3
coefficient=2
row= 3
col = 3
new column header created
coefficient = 0
row = -1
column = 3
rowLink = 0x100103c70
colLink = 0x100103c70
token==4xy2
coefficient=4
row= 1
col = 2
new row header created
coefficient = 0
row = 1
column = -1
rowLink = 0x100103c90
colLink = 0x100103c90
token==y3
coefficient=-1
row= 0
col = 3
new row header created
coefficient = 0
row = 0
column = -1
rowLink = 0x100103cb0
colLink = 0x100103cb0
token==5y
coefficient=5
row= 0
col = 1
token==5
coefficient=5
row= 0
col = 0
new column header created
coefficient = 0
row = -1
column = 0
rowLink = 0x100103cd0
colLink = 0x100103cd0
why no rowheader is created for token=2x3y3 ?
Finally the addresses stored in Array of pointers are:
#Array of row pointers#
- row 0 = 0x100103cb0
- row 1 = 0x100103c90
- row 2 = 0x100103cd0
- row 3 = 0x100103c50
- row 4 = 0x100103c30
#Array of column pointers#
- column 0 = 0x100103cd0
- column 1 = 0x100103c50
- column 2 = 0x100103c30
- column 3 = 0x100103c70
* row 2 is having the same address of column 0,
* row 3 is having the same address of column 1,
* row 4 is having the same address of column 2
It's really hard to figure out what you're trying to do here. Couple of things that stick out:
Remember that for an array of length m, you can only index from 0 to m-1 (not m). Your loop in create_array_with_nullp is going past the end of each of the arrays, corrupting memory.
node **rArr = new node*[m];
//...
for(int i=0; i<=m;i++){ // ouch! should only go to i**<**m
In create_n_link_new_node, did you mean to set the column entry like so:
cArr[b] = new_colheader->rowLink;
or did you actually mean:
cArr[b] = new_colheader;
Are you intending to have each of colheader and rowheader cross-referenced? If so, you would need:
new_colheader->rowLink = new_rowheader;
new_rowheader->colLink = new_colheader;
at the end of create_n_link_new_node.
Again, not really sure what is trying to be accomplished but those things seem suspect at least.