I'm trying to select every second element in the group of three. e.g.
[4, 5, 3, 2, 3, 1, 4, 5, 3]
Result: 5, 3, 5
How can I achieve this?
You can use Array.prototype.filter and modulo operation:
const result = [4, 5, 3, 2, 3, 1, 4, 5, 3].filter((item, i) => (i+2) % 3 === 0);
console.log(result)
var arr = [4, 5, 3, 2, 3, 1, 4, 5, 3],
filtered = arr.filter((val,idx) => idx % 3 == 1);
You have to split the array in chunks, then take the second element of every chunk:
/**
* Returns an array with arrays of the given size.
*
* #param myArray {Array} array to split
* #param chunk_size {Integer} Size of every group
*/
function chunkArray(myArray, chunk_size){
var index = 0;
var arrayLength = myArray.length;
var tempArray = [];
for (index = 0; index < arrayLength; index += chunk_size) {
myChunk = myArray.slice(index, index+chunk_size);
// Do something if you want with the group
tempArray.push(myChunk);
}
return tempArray;
}
// Split in group of 3 items
function getResult () {
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
var chunked = chunkArray([1,2,3,4,5,6,7,8], 3);
var result = [];
for(var i = 0; i < chunked.length; i++){
result.push(chunked[i][1]);
}
return result;
}
console.log(getResult());
Chunking ref: https://ourcodeworld.com/articles/read/278/how-to-split-an-array-into-chunks-of-the-same-size-easily-in-javascript
//this function splits arrays into groups of n
function chunk(arr, limit) {
var chunks = [];
for (var i=0,len=arr.length; i<len; i+=limit)
chunks.push(arr.slice(i,i+limit));
return chunks;
}
var arr = [4, 5, 3, 2, 3, 1, 4, 5, 3]
//split array in groups
var chunked = chunk(arr, 3);
//for each array in chunked array, do something with second item
chunked.forEach(function(i) {
console.log(i[1]);
});
//You can also do:
chunked[2][1]
Related
I have an Array, arr = [2,4,8,7,3,6] I want to make each element of it be summation when the result is 10 , then save the element it would be arranged to another array.
make the element that result is 10 close each other like 2 and 8, add to another element named arr2.
result i need : arr2[2,8,3,7,4,6]
my code :
const arr = [2, 4, 8, 7, 3, 6];
let arr2 = [];
for (let i = 0; i < arr.length(); i++) {
let Number1 = arr[i];
let Number2 = arr[(i + 1)];
if (Number1 + Number2 === 10) {
let element1 = arr.indexOf(Number1);
let element2 = arr.indexOf(Number2);
arr2.push(element1, element2);
}
console.log(arr2[i]);
}
someone can solve my problem please ?
If you need to create arr2 so that the items sum up to 10 you can make use of a simple map here:
const arr = [2, 4, 8, 7, 3, 6];
const arr2 = arr.map((item) => 10 - item)
console.log(arr2);
You should first loop through the array to create a dictionary of value to index, then loop the array again and lookup for the complement of the current value to the target. If it exist then yes you got the answer.
.filter(x => x > i) is to search for complement that has higher index than current one so that we will not get duplicated result pushed. For example input is [2, 8], you don't want to get [2, 8, 8, 2]
Here is my solution
const arr = [2, 4, 8, 7, 3, 6];
let arr2 = [];
function solution(target: number, input: number[]): number[] {
const result: number[] = [];
const lookUpMap: {[key: number]: number[]} = {};
let i = 0;
for (const each of input) {
if (!(each in lookUpMap)) {
lookUpMap[each] = [];
}
lookUpMap[each].push(i);
i++;
}
i = 0;
for (const each of input) {
const difference = target - each;
if (difference in lookUpMap) {
const complementIndex = lookUpMap[difference].filter(x => x > i)[0];
if (complementIndex) {
result.push(input[i], input[complimentingIndex]);
}
}
i++;
}
return result;
}
arr2 = solution(10, arr);
console.log(arr2);
Assuming a valid result can be created for the given arr. A fairly simple solution would be to sort the array first. Then step through half the array and take the element on the current index, and the element on the inverse index (length - 1 - index). And push() those both in the resulting array.
So here in steps, given you have the following array:
[2, 4, 8, 7, 3, 6]
You sort it:
[2, 3, 4, 6, 7, 8]
Then you step through half the indexes and take each element, and the element on the inverse index.
[2, 3, 4, 6, 7, 8]
// \ \ \/ / /
// \ ------ / -> [2, 8, 3, 7, 4, 6]
// ----------
const arr = [2, 4, 8, 7, 3, 6];
const sortedArr = Array.from(arr).sort((a, b) => a - b); // ascending
const length = sortedArr.length;
const nPairs = length / 2;
const arr2 = [];
for (let i = 0; i < nPairs; ++i) {
arr2.push(
sortedArr[i],
sortedArr[length - 1 - i],
);
}
// or if you want a more functional approach:
// const arr2 = Array.from({ length: nPairs }).flatMap((_, i) => [sortedArr[i], sortedArr[length - 1 - i]]);
console.log(arr2);
Do note that this is probably not the fastest solution, because sorting is non-linear.
Obviously this solution does not work if an invalid input is given, like [7,2,1,8] which can never produce a valid output.
So for ex. I have this array with these values :
let arr = [1, 2, 3, 3, 3, 4, 4];
How can I get a new arr as :
let newArr = [3, 3, 4, 4];
while at the same time the original array should be changed as :
let arr = [1, 2, 3];
one 3 is left behind cause there is only one pair of 3.
I tried this code below ( a for loop & splice ) but it is not working properly.
let result = [];
for (let i = 0; i < sorted.length; i++) {
if (sorted[i] === sorted[i + 1]) {
let pair = sorted.splice(i, 1);
pair.forEach(el => result.push(el));
}
}
Few things corrected,
You need to splice two items from the point you see duplicates.
Try like this.
Iteration stop condition should be i < sorted.length - 1 as we consider two consecutive items.
Use Array.prototype.concat to join duplicates to the result array.
let sorted = [1, 2, 3, 3, 3, 4, 4];
let result = [];
for (let i = 0; i < sorted.length - 1; i++) {
if (sorted[i] === sorted[i + 1]) {
let pair = sorted.splice(i, 2);
result = result.concat(pair);
i--;
}
}
console.log(sorted)
console.log(result)
I have array:
arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
Then I want to make group of 4 elements.
Every iteration, this array must be modified until it get's final face.
Step 1:
arr = [[1,2,3,4],5,6,7,8,9,10,11,12,13,14];
Step 2:
arr = [[1,2,3,4],[5,6,7,8],9,10,11,12,13,14];
Step 3:
arr = [[1,2,3,4],[5,6,7,8],[9,10,11,12],13,14];
Step 3:
arr = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14]];
How is this possible?
I tried this:
var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
var i,j,temparray,chunk = 4;
for (i=0,j=array.length; i<j; i+=chunk) {
temparray = array.slice(i,i+chunk);
console.log(temparray);
}
But I don't know then how to save this chunk into own array and not in the new array.
Using Array#reduce method.
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
newArr = arr.reduce((acc, item, index) => {
if ((index) % 4 === 0) {
acc.push([item]);
} else {
acc[acc.length - 1].push(item);
}
return acc;
}, []);
console.log(newArr); // [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ], [ 13, 14 ] ]
You could splice the array until the length is smaller than the index of the last insertation.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
i = 0;
while (i < array.length) {
array.splice(i, 0, array.splice(i, 4));
console.log(JSON.stringify(array));
i++;
}
lodash probably has better performances than my implementation, but if you are looking to do so with vanilla javascript then you can like this (though many other ways are possible):
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
var newArr = arr.reduce((acc, val, idx)=>{
if(idx % 4 === 0){
acc.push([]);
}
acc[acc.length-1].push(val)
return acc
}, [])
console.log(newArr);
The lodash method chunk will do this for you.
result = _.chunk(arr, 4);
function chunkArray(myArray, chunk_size){
var index = 0;
var arrayLength = myArray.length;
var tempArray = [];
for (index = 0; index < arrayLength; index += chunk_size) {
myChunk = myArray.slice(index, index+chunk_size);
// Do something if you want with the group
tempArray.push(myChunk);
}
return tempArray;
}
// Split in group of 3 items
var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);
Just push it to the resulting array:
const chunk = 4, result = []
for (var i = 0, j = array.length; i < j; i += chunk) {
result.push(array.slice(i,i + chunk));
}
I thought it would be fun too if I add one more solution using recursive calls, Happy coding!
Test it here
function split(arr, offset, res){
//stop condition (offset exceeds len of array)
if(offset>arr.length)
return res;
//slice 4 elms
res.push(arr.slice(offset,offset+4));
//recursion
return split(arr, offset+4, res);
}
var res = split([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0, []);
console.log(res);
I want to split an Array of numbers into N groups, which must be ordered from larger to smaller groups.
For example, in the below code, split an Array of 12 numbers into 5 Arrays, and the result should be evenly split, from large (group) to small:
source: [1,2,3,4,5,6,7,8,9,10,11,12]
⬇
output: [1,2,3] [4,5,6] [7,8] [9,10] [11,12]
Playground
// set up known variables
var arr = [1,2,3,4,5,6,7,8,9,10,11,12],
numberOfGroups = 5,
groups = [];
// split array into groups of arrays
for(i=0; i<arr.length; i++) {
var groupIdx = Math.floor( i/(arr.length/numberOfGroups) );
// if group array isn't defined, create it
if( !groups[groupIdx] )
groups[groupIdx] = [];
// add arr value to group
groups[groupIdx].push( arr[i] )
}
// Print result
console.log( "data: ", arr );
console.log( "groups: ", groups )
Update:
Thanks to SimpleJ's answer, I could finish my work.
The use case for this is an algorithm which splits HTML lists into "chunked" lists, a think which cannot be easily achieved by using CSS Columns.
Demo page
I'm not 100% sure how this should work on different sized arrays with different group counts, but this works for your 12 digit example:
function chunkArray(arr, chunkCount) {
const chunks = [];
while(arr.length) {
const chunkSize = Math.ceil(arr.length / chunkCount--);
const chunk = arr.slice(0, chunkSize);
chunks.push(chunk);
arr = arr.slice(chunkSize);
}
return chunks;
}
var arr = [1,2,3,4,5,6,7,8,9,10,11,12];
console.log( chunkArray(arr, 5) )
A shorter version of #SimpleJ answer and without using slice two times.
function splitArrayEvenly(array, n) {
array = array.slice();
let result = [];
while (array.length) {
result.push(array.splice(0, Math.ceil(array.length / n--)));
}
return result;
}
console.log(splitArrayEvenly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 5))
I think this is a more of a mathematical problem than a Javascript.
const getGroups = (arr, noOfGroups) => {
const division = Math.floor(arr.length / numberOfGroups);
const groups = [[]];
let remainder = arr.length % numberOfGroups;
let arrIndex = 0;
for (let i = 0; i < noOfGroups; i++) {
for (let j = division + (!!remainder * 1); j >= 0; j--) {
groups[i].push(arr[arrIndex]);
arrIndex += 1;
}
remainder -= 1;
}
return groups;
};
const myGroups = getGroups([1,2,3,4,5,6,7,8,9,10,11,12], 5);
myGroups will be [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10], [11, 12]]
This will work for any number of groups and players
I have an array:
var myArray = [2, 4, 6];
and another array:
var otherArray = [1, , 3, , 5, , 7];
I'm trying to map (or use any non "for/for-each" iterator) to place each myArray value into the corresponding empty spaces of otherArray.
Hopeful output:
newArray = [1, 2, 3, 4, 5, 6, 7];
Any ideas?
otherArray.forEach(function (val, idx) {
if (typeof val === 'undefined') {
otherArray[idx] = myArray.shift();
}
});
forEach may not be compatible if supporting IE < 9 though.
Using Array.prototype.map:
var newArray = otherArray.map(function(val) {
return typeof val === 'undefined' ? myArray.shift() : val;
});
Be aware that this will not hit indexes that have never been set.
Using while loop:
while (myArray.length > 0) {
var emptyIdx = otherArray.indexOf();
otherArray[emptyIdx] = myArray.shift();
}
Edit: Ok, if the elements in the array are truly not set, as they are in your description, these solutions won't work since they'll skip over the unset indexes. Here's one that would work:
var myArray = [2, 4, 6, 8, 9];
var otherArray = [1, , 3, , 5, , 7];
var lastIdx = -1;
otherArray.forEach(function(val, idx) {
if (idx - lastIdx > 1) {
otherArray[idx - 1] = myArray.shift();
}
});
if (myArray.length > 0) {
otherArray = otherArray.concat(myArray);
}
document.body.innerHTML = otherArray;
You can iterate through the array and check for undefined values like:
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
for (var i = 0, j = 0; i < otherArray.length; i++) {
//check if a value is undefined
if (!otherArray[i]) {
//then change this value with the new from other array
otherArray[i] = myArray[j];
j++;
}
}
console.log(otherArray);//prints [1, 2, 3, 4, 5, 6, 7]
You could use recursivity, this function will fill the undefined items of the first array with the items of the second one until it reach the end of one of the arrays used.
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
function fillArray(ar1, ar2, i){
if (!i) i = 0;
if (!ar1[i]){
ar1[i] = ar2.shift();
}
if (++i < ar1.length && ar2.length > 0){
fillArray(ar1, ar2, i);
}
}
fillArray(otherArray, myArray); // this will update the content of originals arrays,
// use otherArray.slice() to get a copy.
document.getElementById("result").innerHTML = JSON.stringify(otherArray);
<div id="result"></div>
If you want to add elements (because there is other items in myArray and there is no space left in otherArray) you can change the condition to continue replacing the && with ||
if (++i < ar1.length || ar2.length > 0){