How to store Array data into csv format file? - javascript

I have an array and I want to convert that array into a csv file here is my code and how i store my arrays :
const words = ['item1','item2','item3']
const txtNumber = 2;
let newArr = []
for(let t= 1 ; t <= txtNumber ; t++) {
const data = "item1 , item2 , item3 ,item4";
const findWord = (word) => data.split(",").filter(x => x.includes(word))
const array = [];
for(let i = 0; i < words.length ; i++) {
const x = findWord(words[i]);
array.push(x[0])
}
newArr = array.map(x => x === undefined ? '' : x.trim());
console.log(newArr)
}
how can i store newArr values into items.csv into my pc ?

Im a little confused about what the desired output is, so no idea if this helps.
const fs = require('fs')
let writeStream = fs.createWriteStream('output.csv')
const words = ['item1','item2','item3']
const txtNumber = 2;
let newArr = []
for(let t= 1 ; t <= txtNumber ; t++) {
const data = "item1 , item2 , item3 ,item4";
const findWord = (word) => data.split(",").filter(x => x.includes(word))
const array = [];
for(let i = 0; i < words.length ; i++) {
const x = findWord(words[i]);
array.push(x[0])
}
newArr = array.map(x => x === undefined ? '' : x.trim());
//console.log(newArr)
writeStream.write(newArr.map(x=>`"${x}"`).join(",")+"\n")
}
writeStream.end()
The output of this should be (although I have not tested it)
"item1","item2","item3"
"item1","item2","item3"

Store newArr values into items.csv
const fs = require('fs');
const words = ['item1','item2','item3']
const txtNumber = 2;
let newArr = []
for(let t= 1 ; t <= txtNumber ; t++) {
const data = "item1 , item2 , item3 ,item4";
const findWord = (word) => data.split(",").filter(x => x.includes(word))
const array = [];
for(let i = 0; i < words.length ; i++) {
const x = findWord(words[i]);
array.push(x[0])
}
newArr = array.map(x => x === undefined ? '' : x.trim());
console.log(newArr)}
const writeStream = fs.createWriteStream('items.csv');
writeStream.write(`item \n`);
writeStream.write('[ "' + newArr.join('","') + '" ]\n');

Super lazy solution would be, for example, this NPM package found at:
https://www.npmjs.com/package/convert-array-to-csv
Disadvantage would be have an additional dependency to your project which you have no (or little) control over.

Related

how can i put commas in thousands?

`$.ajax({
url : "/selectList.do",
data:{memberNo:memberNo},
success : function(list){
console.log(list);
for(let i=0;i<list.length;i++){
list[i].NUMBER;
}
}
});`
I got numbers from ajax and I want to put a commas in this number in thousands.
How can I do it?
Try use regex
const thousands = (o) => o.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ',');
console.log(thousands(123456789));
console.log(thousands(123456789.123));
Or use Number.prototype.toLocaleString()
const num = 123456.789;
console.log(num.toLocaleString());
Or use Intl.NumberFormat
const number = 123456.789;
const nf = new Intl.NumberFormat('en-US');
console.log(nf.format(number));
Or use Array.prototype
const insert = (arr, index, newItem) => [
...arr.slice(0, index),
newItem,
...arr.slice(index)
];
const thousands = (o) => {
let tmpArr = o.toString().split('.');
let splitArr = tmpArr[0].split('');
const reversed = splitArr.reverse();
for (let i = 1; i <= reversed.length; i++) {
if (i % 3 == 0)
splitArr = insert(splitArr, i, ',');
}
tmpArr[0] = tmpArr.length > 1 ? '.' : '';
return splitArr.reverse().concat(tmpArr).join('');
};
console.log(thousands(123456));
console.log(thousands(123456.789));

How to improve this nested for loop using GAS?

I'd like to learn an alternative way to run this for loop, because currently, it sets the value through each iteration and as this can get large, it better be more performant.
function calculate() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const settingSheet = ss.getSheetByName('settings');
const dataSheet= ss.getSheetByName('Data');
let settingData = settingSheet.getRange(1, 1, settingSheet.getLastRow(), settingSheet.getLastColumn()).getValues();
let spcData = dataSheet.getRange(1, 1, dataSheet.getLastRow(), dataSheet.getLastColumn()).getValues();
let recordTypesAccepted = ['strategy1', 'goal2'];
var settingPar1 = settingData.filter(e => e[0] == 'default').map(e => e[1]);
var settingPar2 = settingData.filter(e => e[0] == 'default').map(e => e[2]);
for (let a = 0; a < spcData.length; a++) {
for (let r = 0; r < settingData .length; r++) {
let settingSearchTerm = settingData[r][4];
let spcSearchTerm = spcData[a][10];
let settingMatchType = settingData[r][5];
let spcMatchType = spcData[a][9];
let spcRecordType = spcData[a][8];
if (recordTypesAccepted.indexOf(spcRecordType) > -1 && settingMatchType === spcMatchType) {
if (settingSearchTerm == spcSearchTerm) {
settingPar1 = settingData[r][7];
settingPar2 = settingData[r][6];
}
let spcClicks = spcData[a][10];
let spcOrders = spcData[a][11];
let row = a + 1;
if (spcClicks >= settingsPar1 && spcOrders >= settingsPar2) {
let newValue = 10;
spcSheet.getRange(row, 20).setValue(newBid).setBackground("#D8E271");
}
}
}
}
}
Thank you!!!
Description
Provided using setValues() doesn't overwrite any formulas you could use getValues() to get an array of the old values, replace any that need to be updated and simply put back the array of values using setValues(). The same for back grounds and number formats.
Note it is assumed from the OP that spcSheet is defined elsewhere.
Script
function calculate() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const settingSheet = ss.getSheetByName('settings');
const dataSheet= ss.getSheetByName('Data');
let settingData = settingSheet.getRange(1, 1, settingSheet.getLastRow(), settingSheet.getLastColumn()).getValues();
let spcData = dataSheet.getRange(1, 1, dataSheet.getLastRow(), dataSheet.getLastColumn()).getValues();
let recordTypesAccepted = ['strategy1', 'goal2'];
var settingPar1 = settingData.filter(e => e[0] == 'default').map(e => e[1]);
var settingPar2 = settingData.filter(e => e[0] == 'default').map(e => e[2]);
let spcRange = spcSheet.getRange(1,20,spcSheet.getLastRow(),1)
var spcValues = spcRange.getValues();
var backgrounds = spcRange.getBackgrounds();
var numberformats = spcRange.getNumberFormats();
for (let a = 0; a < spcData.length; a++) {
for (let r = 0; r < settingData .length; r++) {
let settingSearchTerm = settingData[r][4];
let spcSearchTerm = spcData[a][10];
let settingMatchType = settingData[r][5];
let spcMatchType = spcData[a][9];
let spcRecordType = spcData[a][8];
if (recordTypesAccepted.indexOf(spcRecordType) > -1 && settingMatchType === spcMatchType) {
if (settingSearchTerm == spcSearchTerm) {
settingPar1 = settingData[r][7];
settingPar2 = settingData[r][6];
}
let spcClicks = spcData[a][10];
let spcOrders = spcData[a][11];
if (spcClicks >= settingsPar1 && spcOrders >= settingsPar2) {
let newValue = 10;
spcValues[a][0] = newBid;
backgrounds[a][0] = "#D8E271";
numberformats[a][0] = "€##0.00";
}
}
}
}
spcRange.setValues(spcValues);
spcRange.setBackgrounds(backgrounds);
spcRange.setNumberFormats(numberformats);
}
Reference
Range.getBackgrounds()
Range.setBackgrounds()
Range.getNumberFormats()
Range.setNumberFormats()

How to split an array in many others arrays with two specific sizes?

I'm trying to find out if there is a way in splitting an array into many others arrays, but these arrays should have a length of 4 and 8. Like:
const someArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23,24,25];
output newArray = [[1,2,3,4],
[5,6,7,8,9,10,11,12],
[13,14,15,16],
[17,18,19,20,21,22,23,24],
[25]];
I've seen many solutions to chunk into specific single sizes like:
export const chunk = (array, size) => {
const chunkedArr = [];
let copiedArr = [...array];
const numOfChild = Math.ceil(copiedArr.length / size);
for (let i = 0; i < numOfChild; i++) {
chunkedArr.push(copiedArr.splice(0, size));
}
return chunkedArr;
};
which I've tried to "adapt" for my requirements, but had no success.
Any help?
Cheers!
A simple implementation consuming the array with a recursive function:
const someArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23,24,25];
const iter = (sliceLen, arr, acc = []) =>
arr.length <= sliceLen
? [...acc, arr.slice(0, sliceLen)]
: iter(sliceLen === 4 ? 8 : 4, arr.slice(sliceLen), [...acc, arr.slice(0, sliceLen)])
const r = iter(4, someArray)
console.log(r)
You can use Array.slice() along with appropriate indices to achieve this.
const someArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23,24,25];
let i = 0;
let step = 4;
const newArray = [];
while(i < someArray.length) {
newArray.push(someArray.slice(i, i + step));
i += step;
step = step == 4 ? 8 : 4;
}
console.log(newArray);
One approach to this would be to just swap back and forth between the chunk size for the iteration.
const someArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23,24,25];
console.log(
chunk(someArray, 4, 8)
);
function chunk(input, size1, size2){
const output = [];
let chunkSize = size1;
for (let i = 0; i < input.length;) {
output.push(input.slice(i).slice(0, chunkSize));
i += chunkSize;
chunkSize = (chunkSize === size1 ? size2 : size1);
}
return output;
}

Take a string , evaluate it and find if there is a number and repeat part of string that number of times?

I was writing code and came into this problem,
You have a specific string which is in this form:
d ae2 n s
now we have to decode this in a specific way,
Split it into different parts by spaces to make an array like ["d","ae2","n","s"]
Evaluate each element of the array and find out if there is a number in it.
If there is a number then repeat the string the number of times.
Add it into the array and continue.
So the output array should be
["d","ae","ae","n","s"]
I have already tried a lot but got nothing
I have used this code earlier but it ends on the second string:
var str = "d ae2 n s"
var res = str.split(" ");
alert(res.length);
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
var numbers = str.match(/\d+/g).map(Number);
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
var res2 = result.repeat(numbers);
res[index] = res2;
}
else{
continue;
}
for(var i = 0; i < res.length; i++ ){
console.log(res[x]);
}
}
function checkNum(t){
return /\d/.test(t);
}
// I am a terible coder :/
expected input : d ae2 n s
expected output : ["d","ae","ae","n","s"]
Using fill() and flatMap() methods and
regex replace
/[^0-9]/ - all non numerical chars
/[0-9]/ - all numerical chars
var str = 'd ae2 n s'
var res = str
.split(' ')
.flatMap(i =>
Array(+i.replace(/[^0-9]/g, '') || 1)
.fill(i.replace(/[0-9]/g, ''))
)
console.log(res)
You can simply loop over your array and populate an other array that will hold your result after checking for a number :
const results = [];
"d ae2 n s".split(' ').forEach(token => {
const match = token.match(/\d+/);
if (match) {
const newStr = token.split(/\d/)[0];
for (let i = 0; i < match[0]; i++) {
results.push(newStr);
}
} else {
results.push(token)
}
})
console.log(results);
You can check Seblor's answer for optimized logic. I have modified your code so that it will be easy for you to understand where you went wrong while doing this. I have added comments to your code where I have changed things:
var str = "d ae2 n s"
var res = str.split(" ");
// create a variable to store the output.
var output = [];
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
// map returns an array, so take the first element, it will be your number.
var numbers = str.match(/\d+/g).map(Number)[0];
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
// instead of doing the repeat and updating the current index,
// push the result, i.e. the current string to be repeated "numbers" times into
// the output array.
for (var i = 0; i < numbers; i++) {
output.push(result)
}
}
else{
// if does not contain any number, push the current item to ouput
output.push (std);
continue;
}
}
function checkNum(t){
return /\d/.test(t);
}
console.log(output);
You can do:
const str1 = 'd ae2 n s';
const str2 = 'e d aefg4 m n s';
const regex = /\d+/;
const getResult = input => input.split(' ').reduce((a, c) => {
const n = c.match(regex);
return n
? [...a.concat(c.replace(n, ' ').repeat(n).trim().split(' '))]
: [...a, c];
}, []);
console.log(getResult(str1));
console.log(getResult(str2));
you can use the Array prototype reduce and filter
const input = 'd ae2 n s';
const output = input.split(' ').reduce((memory, current) => {
const numberIndex = current.split('').findIndex(c => !isNaN(c));
const newCurrent = current.split('').filter((_, index) => index !== numberIndex).join('');
if(numberIndex !== -1) {
for(let i = 0; i < parseInt(current[numberIndex]); i++) {
memory.push(newCurrent);
}
} else {
memory.push(current);
}
return memory;
}, []);
console.log(output);
Hope this helped
You can try with following:
let str = "d ae2 n s"
let split = str.split(" ")
let rx = new RegExp("[0-9]")
let res = [];
split.forEach(s => {
if(rx.exec(s) !== null) {
let rxResult = rx.exec(s)
let count = rxResult[0];
let matchIdx = rxResult[1];
for(let i = 0; i < count; i++) {
res.push(s.replace(count, ""))
}
} else {
res.push(s);
}
})

How to create an object/array from a key/value string made up with '/'

Take the following string:
/foo/1/bar/2/cat/bob
I need to parse this into an object or array which ends up being:
foo = 1
bar = 2
cat = bob
var sample = "/foo/1/bar/2/cat/bob".substring(1);
var finalObj = {};
var arr = sample.split('/');
for(var i=0;i<arr.length;i=i+2){
finalObj[arr[i]] = arr[i+1];
}
console.log(finalObj);
const str = '/foo/1/bar/2/cat/bob/test/'
const parts = str.split('/')
.filter(val => val !== '')
const obj = {}
for (let ii = 0; ii < parts.length; ii+=2) {
const key = parts[ii]
const value = parts[ii+1]
obj[key] = !isNaN(value) ? Number(value) : value
}
console.log(obj)
Regular expressions is the tool of choice for all kinds of parsing:
str = '/foo/1/bar/2/cat/bob'
obj = {};
str.replace(/(\w+)\/(\w+)/g, (...m) => obj[m[1]] = m[2]);
console.log(obj);
Just for the fun of it,
let str = "/foo/1/bar/2/cat/bob",
arr = str.split("/"),
obj = {};
arr.shift();
while (arr.length) obj[arr.shift()] = arr.shift();

Categories

Resources