How can I split array of Numbers to individual digits in JavaScript? - javascript

I have an array
const myArr = [ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106 ]
I need to split into digits like this:
const splited = [ 9, 4, 9, 5, 9, 6, 9, 7, 9, 8, 9, 9, 1, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0, 4, 1, 0, 5, 1, 0, 6 ]

You could join the items, split and map numbers.
var array = [ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106],
pieces = array.join('').split('').map(Number);
console.log(pieces);
Same approach, different tools.
var array = [ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106],
pieces = Array.from(array.join(''), Number);
console.log(pieces);

map each number to a string and split the string, and spread the result into [].concat to flatten:
const myArr = [ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106 ];
const splitted = [].concat(...myArr.map(num => String(num).split('')));
console.log(splitted);

You can use reduce function to create a new array and use split to split the number converted to string
const myArr = [94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106]
let newArr = myArr.reduce(function(acc, curr) {
let tempArray = curr.toString().split('').map((item) => {
return +item;
});
acc.push(...tempArray)
return acc;
}, [])
console.log(newArr)

Related

How do I convert a Nest request object with a buffer into JSON?

How do I convert a Nest request object with a buffer into JSON?
Everything I've logged either shows an array of bytes or a string.
Here is my controller:
export class KycresultsController {
#Post()
create(#Body() data: any): string {
const j = data.toJSON();
var buf = Buffer.from(JSON.stringify(data));
var temp = JSON.parse(buf.toString());
var f = temp.data;
console.log(f);
const decodedJsonObject = Buffer.from(f, 'base64').toString('ascii');
console.log(decodedJsonObject);`
And I send this POST:
curl -X POST localhost:3001/kycresults -d "emsample=1&data=2"
I see in my logs:
[
101, 109, 115, 97, 109, 112,
108, 101, 61, 49, 38, 100,
97, 116, 97, 61, 50
]
emsample=1&data=2
[
101, 109, 115, 97, 109, 112,
108, 101, 61, 49, 38, 100,
97, 116, 97, 61, 50
]
emsample=1&data=2
I want to get {emsample: 1, data: 2}

How to get count of elements matching a predicate in a javascript array?

Let's say we want to count the NaN's in a javascript array. We can use
let arr = [...Array(100)].map( (a,i) => i %10==0 ? NaN : i )
console.log(arr)
> [NaN, 1, 2, 3, 4, 5, 6, 7, 8, 9, NaN, 11, 12, 13, 14, 15, 16, 17, 18, 19, NaN, 21, 22, 23, 24, 25, 26, 27, 28, 29, NaN, 31, 32, 33, 34, 35, 36, 37, 38, 39, NaN, 41, 42, 43, 44, 45, 46, 47, 48, 49, NaN, 51, 52, 53, 54, 55, 56, 57, 58, 59, NaN, 61, 62, 63, 64, 65, 66, 67, 68, 69, NaN, 71, 72, 73, 74, 75, 76, 77, 78, 79, NaN, 81, 82, 83, 84, 85, 86, 87, 88, 89, NaN, 91, 92, 93, 94, 95, 96, 97, 98, 99]
let nans = arr.map( aa => isNaN(aa) ? 1 : 0).reduce((acc,a) => acc+a)
console.log(nans)
> 10
That does work.. but it is a bit challenging to remember the reduce() machinery every time. Is there a more concise construct by applying a predicate as so:
arr.count( a => isNan(a))
You can have just a single .reduce where the accumulator is the number of NaNs found so far:
const arr = [...Array(100)].map( (a,i) => i %10==0 ? NaN : i );
const nans = arr.reduce((a, item) => a + isNaN(item), 0);
console.log(nans);
You can filter out the elements that are not NaN.
arr.filter(isNaN).length
//or
arr.filter(function(it){ return isNaN(it); }).length
With forEach loop instead of map and reduce
const nanCount = (arr, count = 0) => (
arr.forEach((num) => (count += isNaN(num))), count
);
const arr = [NaN, 0, 1, 3 , NaN];
console.log(nanCount(arr));
Or while for even bigger...
const arr = [...Array(1e6)].map((a, i) => i % 10 == 0 ? NaN : i);
let
i = arr.length,
nans = 0;
while (i--) {
nans += isNaN(arr[i]);
}
console.log(nans.toExponential());
const arr = [...Array(100)].map((a, i) => i % 10 == 0 ? NaN : i);
const count = (arr, predicate) => {
let c = 0, i = arr.length;
while (i--) c += predicate(arr[i]);
return c
};
const
nans = count(arr, x => isNaN(x)),
sevens = count(arr, x => x % 7 === 0);
console.log(`nans: ${nans}, sevens: ${sevens}`);

Given a range, find missing number in array

Given a range, how is it possible in javascript to find the missing number in an unordered array? For example, if I know the range of an array is [48,79] and the array is:
[56, 76, 48, 69, 60, 68, 57, 58, 52,
72, 61, 64, 65, 66, 73, 75, 77,
49, 63, 50, 70, 51, 74, 54, 59,
78, 79, 71, 55, 67]
The missing number/output would be 62,53.
You should try this
function findNumbers(arr) {
var sparse = arr.reduce((sparse, i) => (sparse[i]=1,sparse), []);
return [...sparse.keys()].filter(i => i && !sparse[i]);
}
var myArr = [56, 76, 48, 69, 60, 68, 57, 58, 52,
72, 61, 64, 65, 66, 73, 75, 77,
49, 63, 50, 70, 51, 74, 54, 59,
78, 79, 71, 55, 67]
var res= findNumbers(myArr );
console.log(res);
EDIT: by the time I posted this, Vinay Kaklotar had posted a much better solution for the OPs updated question.
I would iterate until the missing value's index isn't found:
var arr = [1,2,3,4,5,7,8,9,10];
var i = 1;
while(arr.indexOf(i) !== -1) {
i++;
}
console.log(i);
The above was an answer to the original question before OP edited it. Below is a solution to the updated question.
I'm iterating through the array and comparing each item to a new sequence (n). Every time a missing number is found, it's added to the missing array.
var arr = [1, 2, 4, 5, 6, 9];
var missing = [];
var n = 1;
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== n) {
missing.push(n);
i--;
}
n++;
}
console.log(missing);

Why does my replace methods throws an error?

I want to replace the number in the myArray to either 'even' or 'odd' but it throws an error that TypeError: val.replace is not a function
const myArray = [
[23, 156, 25, 10, 52, 23],
[12, 100, 23, 56, 81, 93],
[42.5, 71, 10, 23, 35, 11, 72, 99],
[11, 100, 99, 102, 13, 8, 12]
];
let arr = myArray.map(item => {
return item.map(val => {
if (val % 2 == 0) {
val.toString();
val.replace(val, "even");
} else {
val.replace(val, "odd");
}
});
});
console.log(arr); //TypeError: val.replace is not a function
You need to return the new value.
String#replace returns a new string with the replaced values, but you do not have a strings here.
const myArray = [
[23, 156, 25, 10, 52, 23],
[12, 100, 23, 56, 81, 93],
[42.5, 71, 10, 23, 35, 11, 72, 99],
[11, 100, 99, 102, 13, 8, 12]
];
let arr = myArray.map(item => {
return item.map(val => {
if (val % 2 == 0) {
return "even";
} else {
return "odd";
}
});
});
console.log(arr);
You don't need to use replace, you simply need to map
const myArray = [
[23, 156, 25, 10, 52, 23],
[12, 100, 23, 56, 81, 93],
[42.5, 71, 10, 23, 35, 11, 72, 99],
[11, 100, 99, 102, 13, 8, 12]
];
let arr = myArray.map(item => item.map(val => val % 2 == 0 ? 'even' : 'odd'))
console.log(arr);
You can try following (Check for value if divisible by 0, if yes return even else odd)
const myArray = [[23, 156, 25, 10, 52, 23], [12, 100, 23, 56, 81, 93], [42.5, 71, 10, 23, 35, 11, 72, 99], [11, 100, 99, 102, 13, 8, 12]];
let arr = myArray.map(item => item.map(val => val%2 === 0 ? "even": "odd"));
console.log(arr);
Or you can improve your code as follows
const myArray = [[23, 156, 25, 10, 52, 23], [12, 100, 23, 56, 81, 93], [42.5, 71, 10, 23, 35, 11, 72, 99], [11, 100, 99, 102, 13, 8, 12]];
let arr = myArray.map(item => {
return item.map(val => {
if (val % 2 == 0) {
val = val.toString(); // you need to reassign after toString
val = val.replace(val, "even"); // you need to reassign after replace
} else {
val = val.toString(); // you need to reassign after toString
val = val.replace(val, "odd"); // you need to reassign after replace
}
return val; // finally you need to return the updated value
});
});
console.log(arr); //Now the right input will be logged

How to change data type of some elements in an array in JavaScript

I would like to change the type of some elements in an (nested) array, and the only way I know is to run a for loop.
Please see the example below:
The data is of the form
var chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
I would like to change to
var new_data = [
[new Date("1980/01/23"), 95, 100, 98, 110],
[new Date("1980/01/24"), 98, 98, 102, 103],
[new Date("1980/01/25"), 90, 102, 95, 105],
[new Date("1980/01/26"), 93, 95, 103, 103],
[new Date("1980/01/27"), 94, 103, 104, 105],
];
The only way I come up with is a for loop
function transform(arr) {
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
var sub_arr = [];
for (var j = 0; j < arr[i].length; j++) {
if (j == 0) {
sub_arr.push(new Date(arr[i][j]));
} else {
sub_arr.push(arr[i][j]);
}
}
new_arr.push(sub_arr);
}
return new_arr
}
alert(transform(chartdata));
Is there better way to achieve this?
Use .map to transform one array into another:
const chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
const newData = chartdata.map(([dateStr, ...rest]) => [new Date(dateStr), ...rest]);
console.log(newData);
For ES5 compatibility, you won't be able to use rest/spread and arrow functions, so another option is:
var chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
var newData = chartdata.map(function(arr) {
var date = new Date(arr[0]);
return [date].concat(arr.slice(1));
});
console.log(newData);
Sure you could simply do this:
const chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
const newData = chartdata.map(arr => {
arr[0] = new Date(arr[0]);
return arr;
});
console.log(newData);
If you don't want to mutate the original array:
const newData = chartdata.map(([...arr]) => {
arr[0] = new Date(arr[0]);
return arr;
});
You can also do it in one line with param destructing like this:
const newData = chartdata.map(([date, ...rArr]) => [new Date(date), ...rArr]);
actually yes, you are copying a lot of times the content of each inner array, using map and assigning the new value would work.
here you have a working example:
var chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
function transform(arr) {
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
var sub_arr = [];
for (var j = 0; j < arr[i].length; j++) {
if (j == 0) {
sub_arr.push(new Date(arr[i][j]));
} else {
sub_arr.push(arr[i][j]);
}
}
new_arr.push(sub_arr);
}
return new_arr
}
function improvedTransform(arr) {
return arr.map(item => {
item[0] = new Date(item[0]);
return item;
})
}
console.log(transform(chartdata));
console.log("-------");
console.log(improvedTransform(chartdata));
You can use map() to create a new array from the existing one:
var chartdata = [
["1980/01/23", 95, 100, 98, 110],
["1980/01/24", 98, 98, 102, 103],
["1980/01/25", 90, 102, 95, 105],
["1980/01/26", 93, 95, 103, 103],
["1980/01/27", 94, 103, 104, 105],
];
var new_data = chartdata.map(function(i){
var date = new Date(i[0]);
date = [date].concat(i.slice(1));
return date;
})
console.log(new_data);

Categories

Resources