This question already has answers here:
Create array of all integers between two numbers, inclusive, in Javascript/jQuery
(21 answers)
Closed 3 years ago.
I have an array with two elements [5, 50]. I want this array iterate as [5, 6, 7,......, 49, 50].
I try below code. But not working as my expectation.
function All(arr) {
let newArry = [];
for(let i = arr[0]; i < arr[1]; i++ ) {
newArry[i] = newArry.push(i);
}
return newArry;
}
console.log(All([5, 50]));
Do like this remove newArry[i] =
function All(arr) {
let newArry = [];
for(let i = arr[0]; i < arr[1]; i++ ) {
newArry.push(i);
}
return newArry;
}
console.log(All([5, 50]));
Get the two values you want to iterate between:
const [start, end] = [5, 50];
Create a new array of length difference between your two points:
Array(end - start + 1) // [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
Since all the values will be undefined, create an iterator object using Array#keys: Array(end - start + 1).keys() // [object Array Iterator]
Spread that into an array:
[...Array(end - start + 1).keys()] // [0, 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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
Map over the values to create your new array:
[...Array(end - start + 1).keys()].map(i => i + start) // [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
...which gives you something like this:
const range = (n, m) => [...Array(m - n + 1).keys()].map(i => i + n);
const [start, end] = [5, 50];
console.log(range(start, end)); // [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
Or, to maintain the API of the function in your question, like this:
const All = (arr) => {
const [n, m] = arr;
return [...Array(m - n + 1).keys()].map(i => i + n);
}
console.log(All([5, 50])); // [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
The Array.prototype.push method mutates the original array, so reassigning doesn't make sense.
Just do:
newArray.push(i);
Related
I want to print all even values in all object key end with odd value but the coding I made just now is only specified for arr1, arr3, and arr5. Can anyone suggest me how to fix 'let oddArr' method (maybe in loop) so that when I changed arr1 into arr7, the result would be the same.
var num = {
arr1 : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
arr2 : [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
arr3 : [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
arr4 : [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
arr5 : [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
};
let oddArr = [...num.arr1, ...num.arr3, ...num.arr5] //need some correction here
let evenNum = oddArr.filter(number => number % 2 == 0);
console.log(evenNum.toString());
//help me fix 'let oddArr' (maybe in loop method) so that when I changed the object of the array (e.g: arr1 -> arr7) it would come out with the same result
//the result/output should be 2,4,6,8,10,22,24,26,28,30,42,44,46,48,50 based on var num
You can try like below using for in loop and it works with any last character as odd.
var num = {
arr1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
arr2: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
arr3: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
arr4: [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
arr7: [41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
};
let oddArr = [];
for (let key in num) {
if (key.charAt(key.length - 1) % 2 !== 0) {
oddArr = [...oddArr, ...num[key]];
}
}
let evenNum = oddArr.filter((number) => number % 2 === 0);
console.log(evenNum.toString());
You might want to use
let oddArr = Object.entries(num).filter( // filter key names
e => +e[0].replace("arr", '') % 2 !== 0 // replace "arr" and check if X in arrX is odd
).map(e => e[1]).flat() // merge values and flattern array
You can also make use of regex if the "arrX"-naming is not consistent:
+e[0].match(/\d+/) % 2 !== 0
See a working snippet below:
var num = {
arr1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
arr2: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
arr3: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
arr4: [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
arr5: [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
};
let oddArr = Object.entries(num).filter(
e => +e[0].replace("arr", '') % 2 !== 0
).map(e => e[1]).flat()
let evenNum = oddArr.filter(number => number % 2 == 0);
console.log(evenNum.toString());
This also works.
var num = {
arr1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
arr2: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
arr3: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
arr4: [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
arr5: [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
arr6: [51, 52, 53, 55, 55, 56, 57, 58, 59, 60],
arr7: [61, 62, 63, 66, 65, 66, 67, 68, 69, 70],
};
var evenNums = Object.keys(num).filter((item) => {
itemNum = item.replace("arr", "");
return itemNum % 2 !== 0;
}).map((o) => num[o]).flat().filter((x) => x % 2 == 0);
console.log(evenNums);
This question already has answers here:
How to compare arrays in JavaScript?
(61 answers)
Triple equal signs return false for arrays in javascript. why?
(4 answers)
Closed 1 year ago.
This is a simple code designed to tell me if one array has an array equal to it in an array consisting of arrays. So the following function should be returning true but it returns false.
var TransferR =[0,8,16,24,32,40,48,56]
var rookV =[
[0,8,16,24,32,40,48,56],
[1,9,17,25,33,41,49,57],
[2,10,18,26,34,42,50,58],
[3,11,19,27,35,43,51,59],
[4,12,20,28,36,44,52,60],
[5,13,21,29,37,45,53,61],
[6,14,22,30,38,46,54,62],
[7,15,23,31,39,47,55,63],
]
const match = rookV.some(memb=> memb === TransferR)
console.log(match)
You can't compare arrays with ===, which compares the references.
Compare array length and then each value.
For example:
const match = rookV.some(memb=> {
memb.length === TransferR.length && memb.every(el => TransferR.includes(el))
});
This code will first check that there is a match in the length (so it will skip arrays that are uncomparable), and than will check that every element of memb is included in the TransferR array, returning true or false.
how about stringify it?
var TransferR = [0, 8, 16, 24, 32, 40, 48, 56]
var rookV = [
[0, 8, 16, 24, 32, 40, 48, 56],
[1, 9, 17, 25, 33, 41, 49, 57],
[2, 10, 18, 26, 34, 42, 50, 58],
[3, 11, 19, 27, 35, 43, 51, 59],
[4, 12, 20, 28, 36, 44, 52, 60],
[5, 13, 21, 29, 37, 45, 53, 61],
[6, 14, 22, 30, 38, 46, 54, 62],
[7, 15, 23, 31, 39, 47, 55, 63],
]
const match = rookV.some(
memb => JSON.stringify(memb) === JSON.stringify(TransferR))
console.log(match)
I'm trying to get my code to do this:
Original array = [1,2,3,4] swap once-> [4,2,3,1] swap again->[4,3,2,1]
Therefore result is 2
But it's not working. Here's what I have so far:
function check(arr){
var sarr = [];
var cnt = 0;
var arrL = arr.length;
// Create a second copy of the array for reference
var arrCopy = [...arr];
for(let i=0; i<arrL;i++){
var maxV = Math.max(...arr);
sarr.push(maxV);
let pos = arr.indexOf(maxV);
// Remove the found number
arr.splice(pos,1);
// Check if the index of the number in the new array is same with the copy, if not then there was a swap
let ai =arrCopy.indexOf(maxV);
let si =sarr.indexOf(maxV);
if (ai !== si && (i+1)!=arrL && pos !== 0){
cnt++;
};
}
console.log(cnt);
}
check([1, 2, 3, 4, 5, 6]);//Result should be 3
check([6,5,4,3,2,1]); //result should be 0
check([1,2,3,4]); //result should be 2
check([1,3,2,5,4,6]); //result should be 3
check([1,2,10,4,5,6,7,8,9,3,12,11]);//result should be 6
check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16]);//result should be 54
Can someone please let me know what I'm doing wrong?
I would start with a copy of the array in descending order for getting the right index of the items.
For practical reasons, (or just a shorter conception of the loop with including check and decrement), I loop from the end of the array.
Then I check the value of array and reversed at the dame index and go on with the iteration.
If not the same value, the items at the wanted position i and the actual position p are swapped and the count incremented.
At the end the count is returned.
function check(array) {
var reversed = array.slice().sort((a, b) => b - a),
count = 0,
i = array.length,
p;
while (i--) {
if (array[i] === reversed[i]) continue;
p = array.indexOf(reversed[i]);
[array[i], array[p]] = [array[p], array[i]];
count++;
}
console.log(...array);
return count;
}
console.log(check([1, 2, 3, 4, 5, 6])); // 3
console.log(check([6, 5, 4, 3, 2, 1])); // 0
console.log(check([1, 2, 3, 4])); // 2
console.log(check([1, 3, 2, 5, 4, 6])); // 3
console.log(check([1, 2, 10, 4, 5, 6, 7, 8, 9, 3, 12, 11])); // 6
console.log(check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16])); // 54
.as-console-wrapper { max-height: 100% !important; top: 0; }
function minimumSwaps(arr) {
var count = 0;
arr.sort((a, b) => {
if (a < b) {
count++;
}
});
return count;
}
console.log(minimumSwaps([1, 2, 3, 4, 7, 6, 5]));
I'm trying to write a function that, given an array and n, returns the array with elements repeating no more than n times. I cannot change the order of the array.
Below is the code I have so far. What is perplexing me is that it works for most elements in a given array, but not for some others. I'm trying to find a rhyme or reason for the elements for which the code does not work.
function deleteNth(arr,n){
arr.forEach(function (item, index) {
var count = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
count++;
while (count > n) {
var remove = arr.lastIndexOf(item);
arr.splice(remove, 1);
count--;
}
}
}
});
return arr;
}
var x = deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35,
35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41,
35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7,
2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2);
console.log(x);
Currently returns this...
[7, 26, 21, 41, 43, 2, 26, 24, 10, 10, 10, 24, 35, 35, 43, 41, 7, 21,
41, 2, 43, 28]
But I should get this...
[7, 26, 21, 41, 43, 2, 26, 24, 10, 10, 24, 35, 35, 43, 41, 7, 21, 2,
28]
Any insight into where I'm going wrong would be sincerely appreciated.
The logic of where you places the while loop is wrong, you need to place it outside of the for loop.
function deleteNth(arr, n) {
arr.forEach(function(item, index) {
var count = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
count++;
}
}
while (count > n) {
var remove = arr.lastIndexOf(item);
arr.splice(remove, 1);
count--;
}
});
return arr;
}
var x = deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35,
35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41,
35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7,
2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10
], 2);
console.log(x);
Why? Because when you are doing your loop and you remove things from it, you shift things back down. So when you have two items side by side and you remove the first the second one shifts down one spot to fill what you just removed. The i does not change so you do not check the item that just filled the gap.
What would I do? I would just keep track of the items as I get to it and if I have not gone over the max append it.
function cleanUp (arr, max) {
const cnts = {} // keep track of what we find
return arr.reduce((a, i) => { // loop over the array index by index
cnts[i] = (cnts[i] || 0) + 1; // mark that I seen the number
if (cnts[i] <= max) { // check to see if we are under the max
a.push(i) //if we are, add it to an arry
}
return a // return the array for reduce
}, [])
}
console.log(cleanUp([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35,
35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41,
35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7,
2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2))
This code works:
function deleteNth(arr,n){
var rem = new Array(), new_arr = new Array();
arr.forEach(function (item, index) {
if(!rem[item]) rem[item]=0;
if(rem[item]<n){
new_arr.push(item);
rem[item]++;
}
});
return new_arr;
}
console.log(deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35, 35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41, 35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7, 2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2));
All of your code is true. Just bring that while out of for loop.
function deleteNth(arr, n) {
arr.forEach(function(item, index) {
var count = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
count++;
}
}
while (count > n) {
var remove = arr.lastIndexOf(item);
arr.splice(remove, 1);
count--;
}
});
return arr;
}
var x = deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35,
35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41,
35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7,
2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10
], 2);
console.log(x);
I like Nina's filter (probably performs better as well) but you can also use reduce:
function deleteNth(arr,n){
return arr.reduce(
([result,map],item)=>{
const count = (map.get(item)||0)+1;
return [
//do not add if more than n of this item have been added already
(count<=n)?result.concat(item):result,
map.set(item,count)//set the new count for this item and return map
]
},
[[],new Map()]//initial value for result and map
)[0];
}
Here is an example using filter and a Map:
function deleteNth(arr,n){
const map = new Map();
return arr.filter(
item=>{
const count = (map.get(item)||0)+1;
map.set(item,count);
return (count<=n);
}
);
}
console.log(deleteNth([1,2,3,2,4,2,5], 2));
If you really want to do it in place, then this answer is not for you. (I think there are very good reasons to work with immutable data, but if you want to mutate, one of the other answers should do it.
Here's one solution that simply keeps a count of each item seen as you go, and filters out those we've seen too often:
const deleteNth = (arr, n) => {
const found = new Map()
return arr.filter(val => {
found.set(val, (found.get(val) || 0) + 1)
return found.get(val) <= n
})
}
const result = deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35, 35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41, 35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7, 2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2)
console.log(result)
One other note: It might offer a nicer API if you choose:
deleteNth = (n) => (arr) => { /* ... */ }
This way you could pass just the repetition count and get back a new function which filters an array.
(Also, this does not sound like a good name for something that delete's all repetitions of a value after the nth one.)
For a fast mutating version, you could use a single while loop, a hash table for counting the items and an adjustment of the index if a splice happens.
function deleteNth(array, n) {
var counter = Object.create(null),
i = 0, v;
while (i < array.length) {
v = array[i];
if (!counter[v]) {
counter[v] = 0;
}
if (++counter[v] > n) {
array.splice(i, 1);
continue;
}
i++;
}
return array;
}
console.log(deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35, 35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41, 35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7, 2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
A better way is to use filter and return a new array.
function deleteNth(array, n) {
var counter = Object.create(null);
return array.filter(v => (counter[v] = (counter[v] || 0) + 1) <= n);
}
console.log(deleteNth([7, 26, 21, 41, 43, 2, 26, 24, 10, 26, 10, 10, 24, 35, 35, 35, 43, 26, 41, 7, 24, 24, 21, 24, 10, 35, 10, 7, 24, 7, 35, 26, 41, 35, 2, 43, 24, 2, 41, 26, 41, 7, 7, 26, 2, 10, 43, 10, 35, 41, 24, 7, 2, 2, 7, 2, 26, 24, 26, 43, 43, 21, 10, 28, 10], 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have an array that can be of any length. and need to split it into sections. The first section will be a length of 14, and there after a length of 16
var size1 = 14;
var size2 = 16;
var a = [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
if (a.length > 14){
for (i = 0; i < 14; i++) {
arrays.push(a.splice(0, size1));
}
for (i = 14 ; i < a.length; i++){
arrays.push(a.splice(0, size2));
}
} else {
arrays.push(a.splice(0, size1));
}
console.log(arrays);
However based on what I am doing my array keeps splitting only at 14. Can you advice on how I can do this?
Thank you
The solution using Array.prototype.slice() function:
var a = [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
size1 = 14,
size2 = 16,
arrays = [];
[0, size1, size2].forEach(function (v, i, arr) {
arrays.push((arr[i+1])? a.slice(v, v + arr[i+1]) : a.slice(arr[i-1] + v));
});
console.log(arrays);
You could use an array for the chunk length and a zero for the rest and map the chunks by keeping the length of the previous lengths.
It works for an arbitrary count of chunks.
var chunks = [14, 16, 0],
array = [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
result = chunks.map((last => a => array.slice(last, a ? (last += a) : undefined))(0));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Edit: so, like this then?
var size1 = 14;
var size2 = 16;
var a = [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var head = a.slice(0, size1);
var arrays = [head];
while (size1 < a.length){
arrays.push(a.slice(size1, Math.min(size1+size2, a.length)));
size1 += size2;
}
console.log(arrays)
You can try this with all dynamic array sizes, it will get you desired output.
Hope you were looking for this solution.
var size1 = 14;
var size2 = 16;
var flag=0;
var a = [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
var t=a.length/14;
while(a.length>0){
if (flag==0 && a.length > 14){
arrays.push(a.splice(0, size1));
flag=1;
} else if(a.length>=16){
arrays.push(a.splice(0, size2));
}
else{
arrays.push(a.splice(0, a.length));
}
}
console.log(arrays)