How to join array elements in pairs in javascript - javascript

I have a array of numbers [1,2,3,4,5,6,7,8,9,10] and I want to make it into a string like this: '1,2 3,4 5,6 7,8 9,10'. Is there some fast and simple vay to do this in javascript or do i have to use the loop?
for(let i = 0; i < array.length; i++){
if(i%2 == 0){
res += array[i] + ',';
} else {
res += array[i] + ' ';
}
}

You can use reduce to get the result you desire:
[1,2,3,4,5,6,7,8,9,10]
.reduce((acc, val, idx) =>
idx % 2 === 0
? (acc ? `${acc} ${val}` : `${val}`)
: `${acc},${val}`, '')
// "1,2 3,4 5,6 7,8 9,10"
By taking advantage of the third parameter of the reduce function we know the index of the element we are currently iterating over, therefore also making this function work for arrays that aren't numbers 1 through 10.

You could get pairs with comma and then join the array with spaces for the string, but you need still a loop
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
temp = [],
i = 0,
string;
while (i < array.length) {
temp.push(array.slice(i, i += 2).join());
}
string = temp.join(' ');
console.log(string);

You could chunk the array, and join the elements with commas and spaces:
var arr = [1,2,3,4,5,6,7,8,9,10,11]
chunkArr = arr.reduce((acc, item, index) => {
const i = Math.floor(index/2)
if(!acc[i]) {
acc[i] = []
}
acc[i].push(item)
return acc
}, [])
arr = chunkArr.map(arr => arr.join(',')).join(' ')
console.log(arr)
Note, this code works with an odd amount of numbers too.

Related

I try to write a function that will return the sum of all array elements that are equal to the number passed in the array. How can I do it?

this function return the sum of all elements in the array
const array = [4, 7, 24, 7, 0, 10];
const number = 7;
function addTheSameNumbers1(number, array) {
let count = array.length;
for (let i = 0; i < count; i++) {
if (array[i] === number) {
return array.reduce((a,b) => a + b, 0);
}
}
return null;
}
console.log(addTheSameNumbers1(number, array));```
Your reduce() is summing all the values. This is how to sum a single number:
const array = [4, 7, 24, 7, 0, 10];
const number = 7;
function addTheSameNumbers1(number, array) {
return array.reduce((accum, val) =>
val === number ? accum + val : accum
, 0);
}
const result = addTheSameNumbers1(number, array);
console.log(result);
If I understand you correctly, you want to get the sum of the elements that have values which are the same to the length of their parent array. This code should do it.
const filterAndSum = (numbers, query) => {
return numbers
.filter((n) => n === query)
.reduce((n, total) => total + n, 0);
};
console.log(filterAndSum([1,2,3,4,5,4,3,2,1,2,3,2,1], 3))
First, it filters the elements which are not equal to the length of the parent array then gets the sum of the remaining elements. Note that validation is not implemented here, but I believe you could easily do that.
You can get the count the occurrence of variable and the multiple with the number
<script>
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
const array = [4, 7, 24, 7, 0, 10];
const number = 7;
var accur = countOccurrences(array, number);
console.log(accur);
console.log(accur * number);
</script>
An alternative to reduce is to use a simple for/of loop to iterate over the numbers, and then add any found numbers to a sum variable.
const array = [4, 7, 24, 7, 0, 10];
const number = 7;
function sumTheSameNumber(n, arr) {
let sum = 0;
for (let i of arr) {
if (i === n) sum += i;
}
return sum;
}
console.log(sumTheSameNumber(number, array));

Getting wrong value while filtering the missing value from array

I want filter the missing number from an sequential array using javascript but I am getting the wrong value. I am explaining my code below.
let arr1 = [1,2,3,4,5,6,7,8,10];
arr1 = arr1.filter((item,pos) => {
if(pos < arr1.length && arr1[pos+1] !== undefined) {
if(item !== arr1[pos+1]-1){
//console.log(item,arr1[pos+1]-1);
return arr1[pos+1]-1;
}
}
})
console.log(arr1);
Here 9 is missing from my array but I am getting the output [8] as output.
You need a different approach, because your filtering returns only a value which is in the array, not missing. As well as you not getting holes of more than one value.
This solution iterates the array and takes a variable for the expected value and if this value is smaller than the array value, it iterates until the given value from the array.
let array = [1, 2, 3, 6, 7, 8, 10],
missing = [],
value = array[0],
i;
for (i = 0; i < array.length; i++) {
while (value < array[i]) missing.push(value++);
++value;
}
console.log(missing);
filter method returns only existing elements which are evaluated to true in callback function:
filter() calls a provided callback function once for each element in
an array, and constructs a new array of all the values for which
callback returns a value that coerces to true.
So filter method cannot return incremented values from existing array.
You can use reduce method for finding gaps:
let arr1 = [1,2,3,4,5,6,7,8,10];
arr1 = arr1.reduce((a, c, i) => {
if ((c + 1) < arr1[i + 1])
a.push(c + 1);
return a;
}, [])
console.log(arr1);
As already said, you can't use filter as its purpose is to filter the values of the given array.
You could try using reduce in order to find multiple gaps:
let arr1 = [1, 2, 4, 5, 6, 7, 8, 12];
arr1 = arr1.reduce((carry, item, index) => {
item++;
while (index !== arr1.length - 1 && item < arr1[index + 1]) {
carry.push(item++);
}
return carry;
}, []);
console.log(arr1);
You can do it as below. Here iterating over all items and check if the difference between current item and previous of current item is 1 or not if not then return (current item -1).
let arr1 = [1,2,3,4,5,6,7,8,10];
for(var i = 1; i < arr1.length; i++) {
if(arr1[i] - arr1[i-1] != 1) {
console.log(arr1[i]-1);
}
}

How to slice the array elements between the stars

I need help for y problem, assume the following array:
let arr = [1,2,3,"*" , 4, "*" , 7 , 8 ,9 ,"*", "10","11", "*", "12" , "*"];
I want to have an output like this:
first array [1,2,3], second array [4], third array [7,8,9] and so on.
I can find all the * with filter but after that I can slice just with indexOf and lastIndexOf to get the first and the last *.indexOf(filteredElement,2) I can't perform a search for * after specific number, because the user input of the * can be different.
Any suggestions?
Thanks in advance guys
You can do it like this with reduce.
Use a temp variable keep on pushing value into it until you don't find a *, as soon as you find a * push this temp variable into output array and reset temp variable.
let arr = [1,2,3,"*" , 4, "*" , 7 , 8 ,9 ,"*", 10,11, "*", 12 , "*"];
let temp = []
let op = arr.reduce((o,c)=>{
if(c !== '*'){
temp.push(c)
} else {
if(temp.length){
o.push(temp);
}
temp=[];
}
return o;
},[])
console.log(op)
Hope this helps,
arr
.join('|')
.split('*')
.filter((d) => d)
.map((d) => d.split('|')
.filter((d) => d));
You could use slice method in combination with while loop statement.
function split_array(arr){
let finalArr = [];
i = 0;
while(i < arr.length){
j = i;
while(arr[j] != "*"){ //find the sequence's end position.
j++;
}
if(i!=j) //treat the case when first array item is *
finalArr.push(arr.slice(i,j));
while(arr[j] == "*"){ //skip consecutive * characters
j++;
}
i = j;
}
return finalArr;
}
console.log(split_array([1,2,3,"*" , 4, "*" , 7 , 8 ,9 ,"*", 10,11, "*", 12 , "*"]));
console.log(split_array(["*",1,2,"*",7,8,9,"*","*",12,"*"]));
A different solution could be to treat the array as a string and match with a regex.
So you match everything but the stars, creating the groupings, and then create you final array with the numbers.
const arr = [1, 2, 3, "*", 4, "*", 7, 8, 9, "*", 10, 11, "*", 12, "*"];
const res = arr.toString()
.match(/[^*]+/g)
.map(v => v.split(',')
.filter(v => v)
.map(v => +v));
console.log(res);
Another possibility with forEach and a bit of filtering:
const splitOnAsterisk = (arr) => {
/* create an array to hold results with an initial empty child array */
let result = [[]];
/* create a new empty array in the result if current element is an asterisk,
otherwise push to the last array in result… */
arr.forEach(v =>
v === "*"
? result.push([])
: result[result.length - 1].push(v)
);
/* filter out empty arrays (if the first/last element was an asterisk
or if there were two or more consecutive asterisks)
[1, 2, "*", 3, "*"]
["*", 1, "*", 2, "*"]
[1, 2, "*", "*", 3] etc…
*/
return result.filter(a => a.length > 0);
}
console.log(splitOnAsterisk([1,2,3,"*",4,"*",7,8,9,"*",10,11,"*",12,"*"]))
console.log(splitOnAsterisk(["*",1,2,"*",7,8,9,"*","*",12,"*"]))
console.log(splitOnAsterisk(["*",1,"*","*",7,8,9,"*","*","*"]))
This can of course be generalised if you need so:
const splitArray = (arr, separator) => {
let result = [[]];
arr.forEach(v =>
v === separator
? result.push([])
: result[result.length - 1].push(v)
);
return result.filter(a => a.length > 0);
}
console.log(splitArray(["❀", "πŸš€", "πŸŽ„", "🐻", "πŸš€", "🐰"], "πŸš€"))
Here is a generalised function to partition an array. Similar to filter, it uses a callback, making it quite versatile.
const partitionArray = (arr, separatorTest) => {
const output = [];
let curr = []; // keep track of the current partition
arr.forEach(el => {
if (separatorTest(el)) { // if we hit a partition split point
output.push(curr); // push the partition to the output
curr = []; // and set the current partition to an empty array for the next partition
}
else {
curr.push(el); // add the current element to the partition
}
});
return output;
}
// usage:
const arr = [1,2,3,'*',4,'*',7,8,9,'*',10,11,'*',12,'*'];
const splitArr = partitionArray(arr, el => el == '*');
Magic (explanation in snippet)
((r=[],i=0)=>(arr.map(x=>x=="*"?i++:(r[i]=r[i]||[]).push(x)),r))();
let arr = [1,2,3,"*" , 4, "*" , 7 , 8 ,9 ,"*", "10","11", "*", "12" , "*"];
let out = ((r=[],i=0)=>( arr.map(x=> x=="*" ? i++ : (r[i]=r[i]||[]).push(x)) ,r))();
console.log(JSON.stringify(out));
// Explanation - we use arrow function to init two variables:
// r=[] and i=0
// then we use arr.map to iterate and check x=="*" if no
// then we put value to r[i], if yes then we increase i and ommit value.
Ok, i'm going with another solution to this problem using the array splice() method. The idea here is to use a while loop and on each loop get an array of the elements that are before the next token separator. The splice() method using on this way will remove elements from the original array, so we can use the length of the array as an stop condition. Note also, that the number of loops required to finish is equal to the number of tokens separators you have into the original array.
let arr = [1, 2, 3, "*", 4, "*", 7, 8, 9, "*", "10", "11", "*", "12", "*"];
let result = [];
let token = "*";
let loopCounter = 0;
while (arr.length > 0)
{
// Remove all elements from original array until find first token.
// Push the removed array of elements inside the result.
result.push(arr.splice(0, arr.indexOf(token)));
// Remove a token separator from the array.
arr.shift();
loopCounter++;
}
console.log(JSON.stringify(result));
console.log(loopCounter);

How to get value from an array, only those what is greater than all elements to its right

I wanted to write a function to get all numbers, what is greater than all elements to its right.
Example if i have an array like this:
arr = [ 75,47,42,56,13,55];
I want a result like this [75,56,55]in a new array.
Other example if i have an array like this:
arr = [16,17,14,3,14,5,2]
I want a result like: [17,14,5,2]
What methods can i use to get this result whatever numbers i have in an array?
You can use filter the array. splice the array to get all the numbers on the right. Use every to check if all array elements are greater than the value.
let arr = [75, 47, 42, 56, 13, 55];
let result = arr.filter((v, i, a) => [...a].splice(i + 1, a.length).every(o => v > o));
console.log(result);
Doc: filter(), splice(), every()
You could simply iterate from the right side and check against the latest found greatest value.
function greaterThanRight(array) {
return array.reduceRight((r, v) => [].concat(v <= r[0] ? [] : v, r), [])
}
console.log([[75, 47, 42, 56, 13, 55], [16, 17, 14, 3, 14, 5, 2]].map(greaterThanRight).map(a => a.join(' ')));
A simple for loop where inner loop has index starting with the index value of the match having highest right value:
var arr = [ 75,47,42,56,13,55];
var res = [];
for(var i=0; i<arr.length; i++){
var highestValue = arr[i];
for(var j=i+1; j<arr.length; j++){
if(highestValue < arr[j]){
highestValue = arr[j];
i = j;
break;
}
}
res.push(highestValue);
}
console.log(res);
var arr = [75,47,42,56,13,55];
arr.sort(function(a, b) {
// a = current item in array
// b = next item in array
return b - a;
});
var newArr = arr.slice(0,3);
console.log(newArr);
Try this. Just start checking from the right.keep a variable max and update it whenever you found a new max
var arr = [ 75,47,42,56,13,55];
function findMaxRight(arr){
var res=[]
var max = Number.MIN_SAFE_INTEGER
for(var i=arr.length -1; i>=0;i--){
if(arr[i]> max){
res.unshift(arr[i])
max = arr[i]
}
}
return res
}
console.log(findMaxRight(arr));
One way to do it could be to loop your array, get the current item and get the rest of the array after the current item using slice.
Then sort the rest of the array descending and get the first entry which is the highest one.
If the current value is larger than the highest one, it is larger then all the values on the right:
let items = [75, 47, 42, 56, 13, 55];
let result = [];
items.forEach((item, index) => {
let head = items[index];
let tail = items.slice(index + 1).sort(function(a, b) {
return b - a;
});
if ((head > tail[0]) || (index === items.length - 1)) {
result.push(head);
}
});
console.log(result);
My solution to do this : find the max and if it's the current number store it, continue with the new array looping = looping.slice(1)
let arr = [75,47,42,56,13,55];
let looping = [...arr];
let finish = arr.reduce( (acc, x) => {
if(x === Math.max(...looping)) acc.push(x);
looping = looping.slice(1);
return acc;
}, [])
console.log(finish) // [75,56,55]

How to take an array, and insert commas between each item?

I am trying to understand how to take an array like [1,2,3,4,5] and then between each index, add a , so the array becomes [1, ', ', 2, ', ', 3, ', ', 4, ', ', 5]
I know it sounds stupid but I'm having some issues with it.
Basically, I want to use something like splice() method, so that I can iterate over the array and each odd index, I can do splice(index, 0, ', ').
You can use .reduce method which accepts as parameter a callback function.
The reduce() method applies a function against an accumulator and each
value of the array (from left-to-right) to reduce it to a single
value.
var array=[1,2,3,4,5];
console.log(array.reduce(function(a,b){
return a.concat(b).concat(",");
},[]).slice(0,-1));
Use .reduce()
Start with empty array
Push an element of array then push ', '
At last remove last ', ' using .pop()
var array1 = [1, 2, 3, 4, 5]
var array2 = array1.reduce(function(acc, val) {
acc.push(val);
acc.push(', ');
return acc;
}, []);
array2.pop();
console.log(array2);
You can use reduce to create a new array with the inserted values:
function weaveArray(array, weaveValue) {
const {length} = array;
return array.reduce((result, value, i) => {
if(i < length - 1) {
result.push(value, weaveValue);
} else {
result.push(value);
}
return result;
}, []);
}
console.log(
weaveArray([1,2,3,4,5], ",")
);
console.log([1,2,3,4,5].reduce(function(acc, val, idx, list) {
acc.push(val);
if (idx < list.length - 1) {
acc.push(',');
}
return acc;
}, []));
With just two methods:
Edit
If you want to save your commas use some regexp instead:
var c = a.join(', , , ').split(/\s(?=,\s)/);
var a = [1,2,3,4,5];
var b = a.join(' , ').split(' ');
var c = a.join(', , , ').split(/\s(?=,\s)/);
console.log(b,c);
Short solution using Array.prototype.join(), Array.prototype.map() and String.prototype.match() functions:
var arr = [1,2,3,4,5],
newArr = arr.join(',').match(/\w+|\W+/g).map(function(v){
return (isNaN(v))? v : +v; // considering numeric values
});
console.log(newArr);
You wanted splice approach? Here it is:
var arr = [1,2,3,4,5];
for (var i = 1; i < arr.length; i+=2) {
arr.splice(i, 0, ',');
}
console.log(arr);
You can use a variable at .splice() to increment index by 2
var arr = [1,2,3,4,5];
for (let i = 1, len = arr.length * 2; arr.length < len - 1; arr.splice(i, 0, ","), i += 2);
console.log(arr);

Categories