How do I iterate nested arrays in a React component? - reactjs

I have a multidimensional array: an array results containing 18 arrays row, each containing 6 numbers.
I want to render this as a table. The logic would be
results.each as (row)
<tr>
row.each as (number)
<td>number</td>
</tr>
But I can't figure out how you'd write this in JSX.
const Resultset = props => (
{props.rows.map(rows => {
<tr>
{rows.map(number => <td>{number}</td>)}
</tr>
})}
);
But that's not right. What's the procedure for this, how do you nest the map calls and interpolations?

One way to do it
var arr = [ [ 2, 3, 4, 5, 6, 7 ],
[ 8, 9, 10, 11, 12, 13 ],
[ 14, 15, 16, 17, 18, 19 ],
[ 20, 21, 22, 23, 24, 25 ],
[ 26, 27, 28, 29, 30, 31 ],
[ 32, 33, 34, 35, 36, 37 ],
[ 38, 39, 40, 41, 42, 43 ],
[ 44, 45, 46, 47, 48, 49 ],
[ 50, 51, 52, 53, 54, 55 ],
[ 56, 57, 58, 59, 60, 61 ],
[ 62, 63, 64, 65, 66, 67 ],
[ 68, 69, 70, 71, 72, 73 ],
[ 74, 75, 76, 77, 78, 79 ],
[ 80, 81, 82, 83, 84, 85 ],
[ 86, 87, 88, 89, 90, 91 ],
[ 92, 93, 94, 95, 96, 97 ],
[ 98, 99, 100, 101, 102, 103 ],
[ 104, 105, 106, 107, 108, 109 ] ];
var Hello = React.createClass({
tablerows: function() {
return this.props.arr.map(rows => {
var row = rows.map(cell => <td>{cell}</td>);
return <tr>{row}</tr>;
});
},
render: function() {
return <table>{this.tablerows()}</table>;
}
});
ReactDOM.render(
<Hello arr={arr} />,
document.getElementById('container')
);
In action: https://jsfiddle.net/69z2wepo/30476/

I would suggest separating the components to Resultset, NumberComponent and try to be consistent with the arrow functions.
// Explicit return
const NumberComponent = props => {
return (
<td>{ props.number }</td>
)
}
const Resultset = props => {
return (
<tr>
{
props.rows.map( number => <NumberComponent number={number} />)
}
</tr>
)
}
// Implicit return
const NumberComponent = props => (<td>{ props.number }</td>);
const Resultset = props => (
<tr>
{
props.rows.map( number => <NumberComponent number={number} />)
}
</tr>
);

This worked well for me to map an array of arrays, I have named the array that contains arrays root, I set up to functions as so:
//root render function
renderNested = (row, i) => {
return (
root.map(function (row, i) {
return (
<div key={i}>
{this.renderNested(row, i)}
</div>
)
}, this)
)
}
//nested render function
renderNested = (row, i) => {
return (
row.map(function (innerrow, ii) {
return(
<span key={ii}>
Nested content here
</span>
)
}, this)
)
}

You can iterate the first part of the array and in the second iteration you can call another component and pass the second array as a prop
const Resultset = props => (
{props.rows.map(rows => {
<tr>
<AnotherComponent rows={rows} />
</tr>
})}
);
In another component you repeat the same map proccess.

Related

pointClick listener on stacked data

curious if there is a way to get the proper index on stacked data (such as a Waterfall diagram) from AnyChart. Using the below on a waterfall gets you the same index for anything click on in a specific stack, when really there should be two index numbers (the column index and the element index within that column).
// add a listener
chart.listen("pointClick", function(e){
var index = e.iterator.getIndex();
});
Thanks
You can get the element index through e.target.getIndex().
anychart.onDocumentReady(() => {
let data = anychart.data.set([
["Start", 23, 30, 21],
["Jan", 22, 22, 54],
["Feb", -46, 45, -32],
["Mar", -91, -30, -28],
["Apr", 37, -27, 36],
["May", -24, 62, -48],
["Jun", 55, 40, -29],
["Jul", 31, 33, 41],
["Aug", -25, -46, 36],
["Sep", 42, 23, 22],
["Oct", 67, -44, -40],
["Nov", -24, -31, 37],
["Dec", 51, 28, 25],
["End", { isTotal: true }, { isTotal: true }, { isTotal: true }],
]);
let seriesData_1 = data.mapAs({ x: 0, value: 1 }),
seriesData_2 = data.mapAs({ x: 0, value: 2 }),
seriesData_3 = data.mapAs({ x: 0, value: 3 });
let chart = anychart.waterfall();
let series1 = chart.waterfall(seriesData_1),
series2 = chart.waterfall(seriesData_2),
series3 = chart.waterfall(seriesData_3);
chart.labels().position("center");
chart.labels().fontColor("white");
chart.listen("pointClick", e => {
let columnIndex = e.iterator.getIndex(),
elementIndex = e.target.getIndex(); // <--- HERE
console.log(`Column index: ${columnIndex}`);
console.log(`Element index: ${elementIndex}`);
});
chart.container("container");
chart.draw();
});
#container {
width: 100%;
height: 350px;
}
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-waterfall.min.js"></script>
<div id="container"></div>
The example above is a modified version of what you can find there: Waterfall Chart | Basic Charts | AnyChart Documentation

Updating ReactJS UI with loop data one after another

I have recently created grid in UI and I want to show the complete flow of motion for all the points given by the array. However, the UI was updated with the value in the last loop.
For ex: position = [1, 2, 3]
At the initial point '1', there is a circle
then the circle move to 2 -> then 3
Instead, moving from 1 to 3
Can anybody help me to achieve this?
My whole class is as follows,
import React, { useEffect, useState } from 'react';
import { Button } from 'reactstrap';
import { motion } from "framer-motion";
import './style.css';
import Grid from './grid'
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
idOfBegin: "1",
position: 0,
xAxis: 0,
yAxis: 0,
position: [],
arrOfObj: [100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
]
};
}
start = () => {
var a = document.getElementById("3");
var codinates = a.getBoundingClientRect();
var x = codinates.left + 35;
var y = codinates.top + 5;
console.log(x, y);
this.setState({ xAxis: x });
this.setState({ yAxis: y });
}
loadPosition = async (event) => {
fetch('api/groups')
.then(response => response.json())
.then(data => {
//console.log('======== ' +data);
//groups.map(group => setPosition(group));
this.setState({ position: data });
});
}
getCellValue = async (event) => {
this.loadPosition();
this.state.position.forEach(p => {
console.log('====== ' + p);
if (p != null) {
var a = document.getElementById(p);
var codinates = a.getBoundingClientRect();
var x = codinates.left + 35;
var y = codinates.top + 5;
//console.log(x,y);
this.setState({ xAxis: x });
this.setState({ yAxis: y });
}
});
}
componentDidMount() {
this.setState({ xAxis: 45 });
this.setState({ yAxis: 905 });
}
render() {
return (
<div>
<div className="grid"><Grid arrOfObj={this.state.arrOfObj} />
<motion.div animate={{ x: this.state.xAxis, y: this.state.yAxis }}
transition={{ type: "tween", duration: 1 }}
></motion.div>
</div>
<div className="control">
<Button color="primary" onClick={() => this.start()}>Start</Button>
<Button color="primary" onClick={() => this.getCellValue()}>Roll Dice</Button>
</div>
</div>
);
}
}
export default Game;

printing a 2D array :warning: excess elements in array initializer

I'm trying to print 8 rows and 5 columns in my output, but my code is throwing errors saying:
warning: excess elements in array initializer.
This is my code:
#include <stdio.h>
void main()
{
int rows,columns;
int array[8][5] =
{
{ 11, 12, 13, 14, 15 }, { 21, 22, 23, 24, 25 },
{ 31, 32, 33, 34, 35 }, { 41, 42, 43, 44, 45 },
{ 51, 52, 53, 54, 55 }, { 61, 62, 63, 64, 65 },
{ 71, 72, 73, 74, 75 }, { 81, 82, 83, 84, 85 },
};
for(columns=0;columns<=4;columns++)
{
for(rows=0;rows<=7;rows++)
{
printf("%d",array[rows][columns]);
}
printf("\n");
}
}
Can anyone please help me fix this code snippet?
You have:
int array[5][8]= {{11,12,13,14,15},{21,22,23,24,25},{31,32,33,34,35},{41,42,43,44,45},{51,52,53,54,55},{61,62,63,64,65},{71,72,73,74,75},{81,82,83,84,85}};
That declares an array of five sub-arrays with eight elements in each sub-array, but you try to initialize it with eight sub-arrays (with five elements in each), and that is why you get the error message about "excess elements". If there were only five sub-arrays with five elements in each, the last three elements in each sub-array would be zeroed.
Fortran does this differently from C. See Wikipedia on Row-major vs Column-major order.
You need to either use int array[8][5] = { … }; or you need to regroup your initializers into five groups of eight, not eight groups of five.
int array[8][5] =
{
{ 11, 12, 13, 14, 15 }, { 21, 22, 23, 24, 25 },
{ 31, 32, 33, 34, 35 }, { 41, 42, 43, 44, 45 },
{ 51, 52, 53, 54, 55 }, { 61, 62, 63, 64, 65 },
{ 71, 72, 73, 74, 75 }, { 81, 82, 83, 84, 85 },
};
Or:
int array[5][8] =
{
{ 11, 12, 13, 14, 15, 21, 22, 23, },
{ 24, 25, 31, 32, 33, 34, 35, 41, },
{ 42, 43, 44, 45, 51, 52, 53, 54, },
{ 55, 61, 62, 63, 64, 65, 71, 72, },
{ 73, 74, 75, 81, 82, 83, 84, 85, },
};
I want 8 rows and 5 columns. Every set of 5 elements should be printed in 8 separate rows.
So you need int array[8][5] — 8 rows with 5 elements in each row. In a 2D array in C, the first index is the row, the second is the column. That means the outer loop runs over rows, the inner loop runs over columns.
#include <stdio.h>
int main(void)
{
int array[8][5] =
{
{ 11, 12, 13, 14, 15 }, { 21, 22, 23, 24, 25 },
{ 31, 32, 33, 34, 35 }, { 41, 42, 43, 44, 45 },
{ 51, 52, 53, 54, 55 }, { 61, 62, 63, 64, 65 },
{ 71, 72, 73, 74, 75 }, { 81, 82, 83, 84, 85 },
};
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 5; col++)
printf(" %d", array[row][col]);
putchar('\n');
}
return 0;
}
Output:
11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
41 42 43 44 45
51 52 53 54 55
61 62 63 64 65
71 72 73 74 75
81 82 83 84 85

How to use data from database in react-chartjs-2 dataset

I have a chart built with react-chartjs-2. The chart displays when I enter the values for data directly in the datasets like this.
datasets: [
{
label: "Active Countries",
backgroundColor: gradientFill,
borderColor: "#2CA8FF",
pointBorderColor: "#FFF",
pointBackgroundColor: "#2CA8FF",
pointBorderWidth: 2,
pointHoverRadius: 4,
pointHoverBorderWidth: 1,
pointRadius: 4,
fill: true,
borderWidth: 1,
data: [80, 99, 86, 96, 123, 85, 100, 75, 88, 90, 123, 155]
}
]
However, I want to replace the value of the data in the datasets with a monthly transaction derived from transactions recorded in my database. The code for my total transaction for each month Jan to Dec ( One for each month) is like this.
const januaryTransactions = transactions.filter(i => {
const date = new Date(i.date);
return date.getMonth() === January && date.getYear() === relevantYear;
}).reduce((prev, curr) => prev + parseFloat(curr.amount), 0)
My question is how do I replace for example the value at in index 0 [80, 99, 86, 96, 123, 85, 100, 75, 88, 90, 123, 155] which is 80 with januaryTransactions .
Any Pointers are mostly appreciated!!

Angular aggregate multiple arrays into one

How do I aggregate in Angular multiple arrays into one? I don't want to concatenate/merge them, but keep them separated with a comma.
var data1 = [65, -59, 80, 81, -56, 55, -40];
var data2 = [28, 48, -40, 19, 86, 27, 90];
Expected:
data = [
[65, -59, 80, 81, -56, 55, -40],
[28, 48, -40, 19, 86, 27, 90]
];
This is not an Angular questions but a javascript question, and while there are many ways to solve this, I will give you one.
var mergedData = [];
var data1 = [65, -59, 80, 81, -56, 55, -40];
var data2 = [28, 48, -40, 19, 86, 27, 90];
mergedData.push(data1);
mergedData.push(data2);
The variable mergedData will now contain
[
[65, -59, 80, 81, -56, 55, -40],
[28, 48, -40, 19, 86, 27, 90]
]
You can create a new array to hold the data, and then just push your arrays into that new array like this:
var data = []
data.push(data1,data2)

Resources