How to change list values/format? - arrays

I'm trying to check a table, that contains "editors" and various "markets" attached to it, and to get a unique list of editors with their number of entries per market.
With this script, I manage to get two list : "editor" and "market":
function JonSnow() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("XX!J1:J114");
var data = range.getDisplayValues();
Logger.log(JSON.stringify(data));
const editor = [];
const market = [];
data.forEach( (val, index) =>{
if(val !="None - regular editor" && val !="N/A" && val !="Cov?" && val !="" && val !="None - no cross-market coverage for this task"){
if(index >= 2 && index <= 12){
markett = "Dach";
}else if (index >= 15 && index <= 30) {
markett = "Dutch";
}else if (index >= 32 && index <= 48) {
markett = "French";
}else if (index >= 52 && index <= 64) {
markett = "Italian";
}else if (index >= 67 && index <= 74) {
markett = "Nordics";
}else if (index >= 77 && index <= 92) {
markett = "polish";
}else if (index >= 95 && index <= 114) {
markett = "Uk";
};
editor.push(val)
market.push(markett)
} else {
return
};
});
Logger.log(editor);
Logger.log(market);
const edunique = [...new Set(editor)];
My next steps would have been to get a list of unique editors and with loops, counting the number of market entries. Problem is, the [...new Set(editor)], doesn't work, and I believe it's because my "editor" list returns [[Name1],[Name2],[Name1]], and should return ["Name1","Name2","Name1"] to work.
Here are my questions :
How do you call to a format like that ? [[],[],[]]
Where did I went wrong and got this ?
How can I fix this, or prevent it ?
Thanks a lot!!
(Sorry if my title is not helpful, as I have no idea what to call the issue I have)

The Range..getDisplayValues() function gets a 2D array. To get a 1D array, use Array.flat(), like this:
const data = range.getDisplayValues().flat();

Related

Pagination is not working in angular JS when the items is below 12 and more than 10

I am using this <github.com/michaelbromley/angularUtils-pagination> Url code. I can able to see the data coming to UI but the pagination is not working consistantly. when there are more than 12 items the pagination is working when there are are less than 12 and more than 10 pagination is not working properly. Please refer to the URL above and suggest a solution. we are suspecting the below code. But not sure where the issue is:
function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) {
var pages = [];
var totalPages = Math.ceil(collectionLength / rowsPerPage);
var halfWay = Math.ceil(paginationRange / 2);
var position;
if (currentPage <= halfWay) {
position = 'start';
} else if (totalPages - halfWay < currentPage) {
position = 'end';
} else {
position = 'middle';
}
var ellipsesNeeded = paginationRange < totalPages;
var i = 1;
while (i <= totalPages && i <= paginationRange) {
var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages);
var openingEllipsesNeeded = (i === 2 && (position === 'middle' || position === 'end'));
var closingEllipsesNeeded = (i === paginationRange - 1 && (position === 'middle' || position === 'start'));
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
pages.push('...');
} else {
pages.push(pageNumber);
}
i++;
}
return pages;
}

Sort and print number of occurences of random numbers

const randomNum = [];
for (let i = 0; i <= 20; i += 1) {
randomNum.push(Math.floor(Math.random() * 20 + 1));
}
then
function getOccurrence(array, value) {
return array.filter((x) => x === value).length;
}
My goal is to print out something along the line of
Number 1, 6, 12, 3, 9 occurred 1 times.
Number 2, 5, 7, 19, 17 occurred 2 times.
Number 15, 11 occurred 3 times.
And so on.
Any idea how i should go about this?
I was thinking of making a function, something along the line of
function numberOccurrence(arr, arrLength){
}
So i in the future could feed it ANY array with with x amount of numbers in it, but I'm unsure how to go forward.
I've tried multiple .includes, .indexOf, ifs and so forth, but i feel stuck, could anyone give me a push in the right direction?
I feel like having a loop which counts how many times 1 occurs, then saves that into an object like this
numObj = {
1: 2,
2: 1,
3: 4,
}
Where the object is built as soon as the function runs, and it builds it based on the arrLength parameter i feed the function in the beginning.
Anything is appreciated, thank you!
Update:
I manage to SOMETIMES print part of the answer right with this:
function getOccurrence(array, value) {
return array.filter((x) => x === value).length;
}
for (let i = 1; i <= randomNum.length; i += 1) {
let numOccurr = [];
for (let j = 1; j <= randomNum.length; j += 1) {
if (randomNum.includes(j)) {
if (getOccurrence(randomNum, j) === i) {
numOccurr.push(j);
if (j === randomNum.length) {
printOut(`Number: ${numOccurr.join(', ')} occurrs ${i} times.`);
numOccurr = [];
}
}
}
}
}
if i check my array after "Number: 20 occurred 4 times" gets printed, i see that the answer is correct, problem is, sometimes it prints every number generated 1 time, then sometimes only those generated 2 times, and so on. And sometimes nothing gets printed
SOLVED:
This code worked for me
const randomNum = [];
for (let i = 0; i < 20; i += 1) {
randomNum.push(Math.floor(Math.random() * 20 + 1));
}
function getOccurrence(array, value) {
return array.filter((x) => x === value).length;
}
for (let i = 1; i <= randomNum.length; i += 1) {
const numOccurr = [];
for (let j = 1; j <= randomNum.length; j += 1) {
if (randomNum.includes(j)) {
if (getOccurrence(randomNum, j) === i) {
numOccurr.push(j);
}
}
}
if (numOccurr.length !== 0)
printOut(`Number: ${numOccurr.join(', ')} occurred ${i} times.`);
}

I'm trying to randomize 5 selections from a list of people

This might be less difficult than I'm making it out to be, but I'm trying to make a Discord.JS bot command, that will take however many arguments I have. For example: !randomize 1,2,3,4,5,6,7,8,9,10
And the bot would respond with something like: "I have chosen: 4,2,7,3,9!" Any help?
Current attempt: Not exactly sure what I'm doing.
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}`
`bot.on('message', async msg => {
if(msg.content === "!add") {
//message.member.user.tag
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var user = args[1];
//if(!args[1]) return msg.channel.send("Please specify an argument!");
if(nameList.includes(user)) {
msg.reply("You're already on the list.")
} else {
nameList.push(args[1]);
msg.channel.send(`${args[1]} has been added to the list!\n Current List:` + nameList);
}
}
if(msg.content === "!bonus") {
if(nameList.length === 0) {
msg.reply("Either the list is empty, or I'm not in the mood!");
} else {
shuffleArray(nameList);
var chosenOne = nameList.pop();
nameList = [];
msg.reply(chosenOne + ' has been chosen! Good luck!');
}
}
if(msg.content === "!list") {
if(nameList.length === 0) {
msg.channel.send("Either the list is empty, or I'm not in the mood!");
} else {
msg.channel.send('The current list:' + nameList);
}
});```
Here's some simple steps to select 5 random elements from an array...
Construct an array of possible selections. In this example I've used names for the first 10 letters of the alphabet. In your code, it'll be the command arguments or predefined nameList.
Make a new array to hold the elements picked.
At some point before #3, you should check to make sure the pool the user has provided is large enough to make 5 selections (Array.length).
Use a for loop to execute the next code multiple times.
Generate a random number representing the index of a selected element (Math.random(), Math.floor()/double NOT bitwise operator).
Push the selection into the array.
Remove the chosen element from the original pool (Array.splice()).
Return the results.
const pool = ['Albert', 'Bob', 'Charlie', 'David', 'Edward', 'Francis', 'George', 'Horacio', 'Ivan', 'Jim'];
const selected = [];
for (let i = 0; i < 5; i++) {
const num = ~~(Math.random() * pool.length);
selected.push(pool[num]);
pool.splice(num, 1);
}
console.log(`I have chosen: ${selected.join(', ')}`);
Take this example and manipulate it within your code to suit your purpose.

Function inside JSX, is not returning the elements: ReactJS

I am trying to add extra rows on a table that is generated using results.map, but the code that I have added to generate the extra rows isn't executing. Does anyone know why this wouldn't work?
< tbody >
{
results.map(result => {
let rowNodes = [];
rowNodes.push(<td className="hidden">{result.itemCtrlType}</td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item">{result.metric}</td>);
} else {
rowNodes.push(<td className="in-td-item hidden">{result.metric}</td>);
}
for (const hour in result) {
if (hour.indexOf('t') == 0 && hour.length == 3) {
let now = Date.now();
let d = new Date(now);
let hours = d.getHours();
let time = hours.toString();
if (hours < 10) {
time = 't0' + hours;
}
else {
time = 't' + hours;
};
let classname = "in-td";
if (hour == time && this.props.dateAdjust == 0) {
classname += " cell-timenow";
}
if (hour == 't23') {
classname += " table-lastcolumn";
}
let date = [pad(d.getMonth() + 1), pad(d.getDate()), d.getFullYear()].join('/');
rowNodes.push(<td key={hour} className={classname} >{result[hour]}</td>)
}
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
return <tr key={result.metric} onClick={this.handleClick}>{rowNodes}</tr>
})
}
{
() => {
console.log(this.props.rowsCount > results.length);
if (this.props.rowsCount > results.length) {
let diff = this.props.rowsCount - results.length;
var rowNodes = [];
for (let m = 0; m < diff; m++) {
rowNodes.push(<td className="hidden"></td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item"></td>);
} else {
rowNodes.push(<td className="in-td-item hidden"></td>);
}
for (let n = 0; n < 24; n++) {
rowNodes.push(<td className="in-td"></td>);
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
return <tr>{rowNodes}</tr>
}
}
}
}
</tbody>
I have tried various combinations of wrapping it in divs or changing where it returns but nothing seems to work.
Anyone know why this isn't firing?
First of all, that is not a good way of organising code, instead of putting the function directly inside JSX, better to define it outside of render method and then call.
Solution:
Issue with your code is, you defined a function inside JSX, but you are not calling it, Use IIFE and call that function, also return null when if condition fails, Like this:
{
(() => {
console.log(this.props.rowsCount > results.length);
if (this.props.rowsCount > results.length) {
let diff = this.props.rowsCount - results.length;
var rowNodes = [], elements = [];
for (let m = 0; m < diff; m++) {
rowNodes = [];
rowNodes.push(<td className="hidden"></td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item"></td>);
} else {
rowNodes.push(<td className="in-td-item hidden"></td>);
}
for (let n = 0; n < 24; n++) {
rowNodes.push(<td className="in-td"></td>);
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
elements.push(<tr key={m}>{rowNodes}</tr>);
}
return elements;
}
return null;
})()
}
Note:
Whenever execution find return statement inside for loop, it will immediately break the loop and return that result, so instead of using return use one more variable and put the tr inside that, Return the result only after for loop completion.
Suggestion:
Assign unique key to each dynamically created elements inside loop.
Check DOC.
Check this answer for more details about keys: Understanding unique keys for array children in React.js

how do I find an object's index number in an array

I've got this code that is looking for the closest number to 0 in my array :
var tideArray = new Array();
tideArray.push({tide:"haute", difference: "-14"});
tideArray.push({tide:"haute", difference: "3"});
tideArray.push({tide:"basse", difference: "-4"});
tideArray.push({tide:"basse", difference: "8"});
if (tideArray.length > 0)
{
var minItem: Object = tideArray[0];
for (var index:int = 1; index < tideArray.length; index++)
{
if (Math.abs(tideArray[index].difference) < Math.abs(minItem.difference))
{
minItem = tideArray[index];
}
}
}
trace(minItem.difference) // OUTPUT is 3 in this case
s there a way to find the index of minItem.difference in my tideArray ? (so, the result here should be index = 1 )
I've tried tideArray.indexOf(minItem.difference) but the output is -1, so the index wasn't found...
I'm looking for the index number and not the value of "difference" or "tide".
Try using map, e.g.:
tideArray.map(function (cv) { return cv.difference }).indexOf("-14")
A really simple approach would be to record the index using your existing loop:
if (tideArray.length > 0)
{
var mindex: int = NaN;
var minItem: Object = tideArray[0];
for (var index:int = 0; index < tideArray.length; index++)
{
if (Math.abs(tideArray[index].difference) < Math.abs(minItem.difference))
{
minItem = tideArray[index];
mindex = index;
}
}
trace("Min item index: " + mindex);
}

Resources