how can i put commas in thousands? - javascript

`$.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));

Related

How to store Array data into csv format file?

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.

How to merge two arrays of dates and keep the order for other array

I have this code:
var dates1 = ['1/2021', '1/2021', '12/2020'];
var values1 = ['-2500', '-150', '-10000'];
var dates2 = ['2/2021', '3/2021', '1/2021'];
var values2 = ['3000', '1000', '3000'];
What I need is to merge the dates1 with dates2, and keep the same order for values1 and values2 adding a 0 for the dates that has none values, so the result would be this:
var dates = ['12/2020', '1/2021', '2/2021', '3/2021'];
var values1 = ['-10000', '-2650', '0', '0'];
var values2 = ['0', '3000', '3000', '1000'];
To merge the arrays of dates I'm using this code:
var dates = dates1.concat(dates2);
I just don't know how can I keep the same order for values1 and values2 adding a 0 for none values.
Any suggestion ? Thank you !
Break down the algorithm into the smallest steps, then order the steps after each other:
const dates1 = ['1/2021', '1/2021', '12/2020'];
const values1 = ['-2500', '-150', '-10000'];
const dates2 = ['2/2021', '3/2021', '1/2021'];
const values2 = ['3000', '1000', '3000'];
// summing the arrays & keeping track of how
// the values should be ordered
const reduceArr = ({ dates, values }) => {
const reduced = dates.reduce((a, c, i) => {
if (typeof a[c] === 'undefined') a[c] = 0
a[c] += Number(values[i])
return a
}, {})
const filteredDates = [...new Set([...dates])]
const filteredValues = filteredDates.map(date => reduced[date])
return {
filteredDates,
filteredValues,
}
}
// merging the different dates arrays
const mergeDates = ({ dates1, dates2 }) => {
return [...new Set([...dates1, ...dates2])]
}
// time-sorting the merged arrays
const sortDates = ({ dates }) => {
return [...dates].sort((a, b) => {
const [m1, y1] = a.split('/')
const [m2, y2] = b.split('/')
return new Date(y1, m1, 1) - new Date(y2, m2, 1)
})
}
// mapping values based on the orders &
// adding 0 if no value is found
const mapToDates = ({ sortedDates, reducedArr }) => {
return sortedDates.map(date => {
const idx = reducedArr.filteredDates.indexOf(date)
return idx === -1 ? 0 : reducedArr.filteredValues[idx]
})
}
// actually executing the steps:
const mergedDates = mergeDates({ dates1, dates2 })
const sortedDates = sortDates({ dates: mergedDates })
const reducedArr1 = reduceArr({ dates: dates1, values: values1 })
const mapValues1 = mapToDates({ sortedDates, reducedArr: reducedArr1 })
const reducedArr2 = reduceArr({ dates: dates2, values: values2 })
const mapValues2 = mapToDates({ sortedDates, reducedArr: reducedArr2 })
console.log('mapValues1', mapValues1)
console.log('mapValues2', mapValues2)
I think that what you need is that:
Array.prototype.unique = function() {
var a = this.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
};
stringToDate = function(str) {
return str.substring(str.search("/")+1, str.search("/")+5) + "-" + (Number(str.substring(0, str.search("/"))) < 10 ? '0' : '') + str.substring(0, str.search("/") ) + "-15T00:00:00Z";
}
dateToString = function(dt) {
dt = new Date(dt);
return (1 + dt.getMonth()) + "/" + dt.getFullYear() ;
}
var dates1 = [stringToDate('1/2021'), stringToDate('1/2021'), stringToDate('12/2020')];
var values1 = ['-2500', '-150', '-10000'];
var dates2 = [stringToDate('2/2021'), stringToDate('3/2021'), stringToDate('1/2021')];
var values2 = ['3000', '1000', '3000'];
var dates_out = dates1.concat(dates2).unique().sort();
var values1_out = new Array(dates_out.length);
var values2_out = new Array(dates_out.length);
dates_out.forEach((dt, i) => {
dates_out[i] = dateToString(dates_out[i]);
values1_out[i] = 0;
values2_out[i] = 0;
dates1.forEach((dt1, i1) => {
if (dt1 === dt) {
if (values1_out[i] != undefined)
values1_out[i] = values1_out[i] + Number(values1[i1]);
else
values1_out[i] = Number(values1[i1]);
}
});
dates2.forEach((dt2, i2) => {
if (dt2 === dt) {
if (values2_out[i] != undefined)
values2_out[i] = values2_out[i] + Number(values2[i2]);
else
values2_out[i] = Number(values2[i2]);
}
});
});
console.log(dates_out);
console.log(values1_out);
console.log(values2_out);
I don't know if this is the best solution. I would create dictionaries to work with the data.
I understood that you need to order the dates (the first result being 12/2020 instead of 1/2021). I also understood that you need the dates as a string, but if you need the date as a datatype, you can remove the part where I convert it back to a string.
here is the solution in python, conversion to javascript should be straight forward. 1. build a list of tuples for dates1/values1 and dates2/values2. 2. Get a list of unique dates. 3. Reduce the tuple lists to a dictionary accumulating on the key which is the date. 4. Using the dates list and the dictionaries create the result value1 and 2 list.
def ReduceToDictionary(tuples):
dict={}
for item in tuples:
key = item[0]
value = item[1]
if key in dict:
dict[key] += float(value)
else:
dict[key] = float(value)
return dict
def BuildList(dates,dict):
result_values=[]
for date in dates:
if date in dict:
val=dict[date]
result_values.append(val)
else:
val=0
result_values.append(val)
return result_values
def StrToDate(string):
groups=re.match('(\d{1,2})[/](\d{4})',string)
year=int(groups[2])
month=int(groups[1])
return(datetime.datetime(year,month,1))
dates1 = ['1/2021', '1/2021', '12/2020']
values1 = ['-2500', '-150', '-10000']
dates2 = ['2/2021', '3/2021', '1/2021']
values2 = ['3000', '1000', '3000']
tuple1=[(StrToDate(dates1[i]),values1[i]) for i in range(len(dates1))]
tuple2=[(StrToDate(dates2[i]),values2[i]) for i in range(len(dates2))]
dates=sorted(set(list(map(StrToDate,dates1))+list(map(StrToDate,dates2))))
dict1=ReduceToDictionary(tuple1)
dict2=ReduceToDictionary(tuple2)
result_values1=BuildList(dates,dict1)
result_values2=BuildList(dates,dict2)
date_string=[date.strftime("%Y/%m") for date in dates]
print(date_string)
print(result_values1)
print(result_values2)
output:
['2020/12', '2021/01', '2021/02', '2021/03']
[-10000.0, -2650.0, 0, 0]
[0, 3000.0, 3000.0, 1000.0]

Summing numbers from 1st array if 2nd array match

I have 2 arrays that looks like this:
amountArray = ["200","150","500","100"];
currencyArray = ["EUR","EUR","USD","USD"];
I'd like to sum amounts from 1st array if 2nd array match.
Result i'd like to get :
totalAmount = "350 EUR | 600 USD";
You could take a Map for collecting same currencies and get the joined values.
let amounts = ["200", "150", "500", "100"],
currencies = ["EUR", "EUR", "USD", "USD"],
result = Array
.from(
currencies.reduce(
(m, c, i) => m.set(c, (m.get(c) || 0) + +amounts[i]),
new Map
),
([k, v]) => [v, k].join(' ')
)
.join(' | ');
console.log(result);
Store your data in a hashmap with the currencies as keys. Then while looping through your amounts, if the key exists, add to the existing sum.
At the end, convert back to an array and print.
const amountArray = ["200","150","500","100"];
const currencyArray = ["EUR","EUR","USD","USD"];
const result = {};
amountArray.forEach((amt, idx) => {
const amountInt = parseInt(amt, 10);
const currency = currencyArray[idx];
const existingTotal = result[currency] || 0;
result[currency] = existingTotal + amountInt;
});
const resultArray = Object.keys(result).map(key => `${result[key]} ${key}`);
const totalAmount = resultArray.join(' | ');
console.log(totalAmount);
You could do this
amountArray = ["200","150","500","100"];
currencyArray = ["EUR","EUR","USD","USD"];
var res = {}
currencyArray.forEach((elem, index)=>{
res[elem] = res[elem] ? parseInt(res[elem]) + parseInt( amountArray[index]) : parseInt(amountArray[index])
});
console.log(res);
var totalAmount = '';
for(var key in res){
totalAmount += ` ${res[key]} ${key} |`;
}
console.log(totalAmount.substr(0, totalAmount.length-1))
If possible, you can creat a class that contains 2 fields, 1 is amount, 1 is corresponding currency. Then you can group by currency and then do the sum up
amountArray = ["200","150","500","100"];
currencyArray = ["EUR","EUR","USD","USD"];
var totalAmount = [];
var result = amountArray.reduce(function(result, field, index) {
//console.log(field);
if(!(currencyArray[index] in result)){
//console.log("afaff");
result[currencyArray[index]] = 0;
}
result[currencyArray[index]] = result[currencyArray[index]] + parseInt(field);
//console.log(result)
return result;
}, {})
console.log(totalAmount);
//totalAmount = "350 EUR | 600 USD";
You could use reduce function to get the desired result.
let amountArray = ["200","150","500","100"];
let currencyArray = ["EUR","EUR","USD","USD"];
let result = currencyArray.reduce((acc,c,i) => {
if(acc.hasOwnProperty(c)){
return{
...acc,
[c]:parseInt(acc[c])+parseInt(amountArray[i])
}
}else{
return{
...acc,
[c]:amountArray[i]
}
}
},{})
console.log(result)
Use forEach to go over both arrays and build one object with accumulated values.
Then use map and join to make required string.
amountArray = ["200", "150", "500", "100"];
currencyArray = ["EUR", "EUR", "USD", "USD"];
const res = {};
currencyArray.forEach(
(key, i) => (res[key] = (res[key] ?? 0) + Number(amountArray[i]))
);
const str = Object.entries(res)
.map(([key, sum]) => `${sum} ${key}`)
.join(" | ");
console.log(str);
I have used java to solve this..
String[] amountArray = {"200","150","500","100"};
String[] currencyArray = {"EUR","EUR","USD","USD"};
HashMap<String, Integer> map = new HashMap<>();
for(int i =0; i < currencyArray.length;i++)
{
Integer n = Integer.parseInt(amountArray[i]);
Integer old = map.get(currencyArray[i]);
if(old == null)
{
old = new Integer(0);
}
Integer val = n+old;
map.put(currencyArray[i], val);
}
A hashmap solution. The first part forms the hashmap which uses currency as key and amount array as value. The second part constructs the string result. The time complexity is O(n^2), space complexity is O(n). n is the length of amountArray or currencyArray.
const amountArray = ["200","150","500","100"];
const currencyArray = ["EUR","EUR","USD","USD"];
function getTotalAmount() {
// --- First Part ---- //
const map = new Map()
const uniqueCurrencyArray = [];
for (let i = 0; i < currencyArray.length; i++) {
if (!uniqueCurrencyArray.includes(currencyArray[i])) {
uniqueCurrencyArray.push(currencyArray[i]);
}
}
for(const currency of uniqueCurrencyArray) {
const result = []
for(const [index, cur] of currencyArray.entries()) {
if(cur === currency) {
result.push(amountArray[index])
}
}
map.set(currency, result)
}
// --- Second Part -- //
let finalResult = ""
for(const key of map.keys()) {
if(finalResult !== "") {
finalResult += " | "
}
const amountArr = map.get(key)
let totalAmount = 0
for(const amount of amountArr) {
totalAmount += parseInt(amount, 10)
}
finalResult += `${totalAmount} ${key}`
}
return finalResult
}
console.log(getTotalAmount())

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);
}
})

Categories

Resources