Related
i have an array like this
const arr = [1,2,3,4,5,6,7];
i am trying to make sub arrays from this main array so that it will look something like this
const splitArray = [[1,4], [2,5], [3,6], [7]];
what i have tried so far is
const convertToSubArray = (array, chunkSize = 2) => {
let i, j, accum = [];
for (i=0, j=array.length; i<j; i+=chunkSize) {
accum = [...accum, array.slice(i, i+chunkSize)];
}
return accum;
}
But getting this as the output
[
[
1,
2
],
[
3,
4
],
[
5,
6
],
[
7
]
]
How can i achieve this, any help is appreciated
You could take a group of six items as offset and inside of each group of six take another offset build by the half of items (p) in this group.
p indices grouping comment
--- ------------- -------------------------- --------------
3 0 1 2 3 4 5 [[0, 3], [1, 4], [2, 5]]
3 0 1 2 3 4 [[0, 3], [1, 4], [2]]
2 0 1 2 3 [[0, 2], [1, 3]]
2 0 1 2 [[0, 1, 2]] special case
1 0 1 [[0, 1]] "
1 0 [[0]] "
At iterating check if the last index in the group is odd, then take a a single value instead of a pair of values.
const
chunk = array => {
const result = [];
for (let offset = 0; offset < array.length; offset += 6) {
const l = Math.min(array.length - offset, 6);
if (l <= 3) {
result.push(array.slice(offset, offset + 3));
break;
}
for (let i = 0, p = Math.ceil(l / 2); i < p; i++) {
result.push(i + 1 === p && l & 1
? [array[offset + i]]
: [array[offset + i], array[offset + i + p]]
);
}
}
return result;
};
console.log(chunk([1]));
console.log(chunk([1, 2]));
console.log(chunk([1, 2, 3]));
console.log(chunk([1, 2, 3, 4]));
console.log(chunk([1, 2, 3, 4, 5]));
console.log(chunk([1, 2, 3, 4, 5, 6]));
console.log(chunk([1, 2, 3, 4, 5, 6, 7]));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8]));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
const arr = [1, 2, 3, 4, 5, 6, 7]
const splitArray = [];
for (i = 0; i < arr.length; i++) {
if (arr[i + 3] != undefined) {
splitArray.push([arr[i], arr[i + 3]])
}
}
console.log(splitArray);
So, as an input I have two arrays, A and B. Let's suppose that these are the values inside the two:
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and B = [1, 3, 5, 7, 9]
After the deletion the array A should be [2, 4, 6, 8, 10].
I have written (Javascript) this functioning algorithm to solve this problem:
for (var i=0; i < A.length; i++) {
for (var j=0; j < B.length; j++) {
if(B[j] == A[i])
A.splice(i, 1) // Removes 1 element of the array starting from position i
}
}
I would like to know, is it possible to solve this problem without using a double loop?
What about this:
let A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ;
const B = [1, 3, 5, 7, 9];
A = A.filter(num => !B.includes(num));
Yes it is. You could use a Set. In terms of Set operations you are computing the difference A \ B.
Using a set which is optimized for lookups in O(1) time will speed up the computing the difference siginificantly from O(n²) when using includes() or double for loop to O(n).
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const B = [1, 3, 5, 7, 9]
const setB = new Set(B);
const difference = A.filter(x => !setB.has(x));
console.log(difference);
Maybe that ?
const
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
, B = [1, 2, 3, 5, 7, 9] // no gaps in 1,2 and 2,3
;
for (let i =0, j=0 ; i < A.length; i++)
{
if (A[i]===B[j]) { A.splice(i--,1); j++ }
}
document.write( JSON.stringify(A) )
or (faster code)
const
A = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
, B = [ 1, 3, 5, 7, 9 ]
;
for (let i = A.length, j= B.length -1 ; i-- ; )
{
if (A[i]===B[j]) { A.splice(i,1); j-- }
}
document.write( JSON.stringify(A) )
Hey guys I m trying to loop over the array of numbers, and what i want my function to do is whenever it is position of a number in array is EVEN number I want a program to return me 'Yan' word in stead of number. but when the position of a number is ODD number i want it to return just a number.
But for some reason in the middle of the array I am getting 'Yan' word instead of getting a number.
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
const myArray = []
const validateCard = (arr) =>{
for(let i = 0; i < arr.length; i++){
if(arr.indexOf(reversValid1[i])%2 == 1){
console.log('Yan')
}
else{
console.log(arr[i])
}
}
}
validateCard(reversValid1)
I m getting the following response:
8
Yan
8
Yan
1
Yan
8
Yan
9
Yan
Yan
Yan
9
Yan
5
Yan
You can see i m getting 3 Yan consecutively.
Why instead of use indexOf don't use directly i ?
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
const myArray = []
const validateCard = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (i % 2 == 1) {
console.log('Yan')
} else {
console.log(arr[i])
}
}
}
validateCard(reversValid1)
The problem is indexOf will find multiple index of same number.
Example:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
for (let i = 0; i < reversValid1.length; i++) {
console.log(reversValid1[i], reversValid1.indexOf(reversValid1[i]))
}
As you can see the same number have same index instead of index of array.
You can use Array.forEach:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.slice().reverse();
const validateCard = (arr) => {
arr.forEach((v,i)=>{
if (i%2 == 0) {
console.log('Yan');
} else {
console.log(v);
}
});
};
validateCard(reversValid1);
This might be what you want:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.reverse();
const myArray = []
const validateCard = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
console.log('Yan');
}
else {
console.log(arr[i]);
}
}
}
validateCard(reversValid1);
Or this:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.reverse();
const validateCard2 = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0) {
console.log('Yan');
}
else {
console.log(arr[i]);
}
}
}
validateCard2(reversValid1);
I have an array with duplicate values
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
I want to set the repeated values to 0:
[0, 0, 0, 0, 7, 8, 0, 0, 2, 0, 6, 4, 0]
can find out the repeated value, but I want to change the repeated value to 0, is there any better way?
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
Array.prototype.duplicate = function () {
let tmp = [];
this.concat().sort().sort(function (a, b) {
if (a == b && tmp.indexOf(a) === -1) tmp.push(a);
});
return tmp;
}
console.log(ary.duplicate()); // [ 1, 3, 5, 9 ]
// ? ary = [0, 0, 0, 0, 7, 8, 0, 0, 2, 0, 6, 4, 0];
You could use indexOf() and lastIndexOf() method to solve your problem.
const array = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
const ret = array.map((x) =>
array.indexOf(x) !== array.lastIndexOf(x) ? 0 : x
);
console.log(ret);
const ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
// get set of duplicates
let duplicates = ary.filter((elem, index, arr) => arr.indexOf(elem) !== index)
duplicates = new Set(duplicates);
// set duplicate elements to 0
const res = ary.map(e => duplicates.has(e) ? 0 : e);
console.log(...res);
First, count values and store them in an object. Then loop over the array and check from that stored object whether the count of specific value is greater than 1 or not, if greater than 1, set that to 0. Here is the working example:
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
let countValue = {}, len = ary.length;
for (i = 0; i < len; i++) {
if (countValue[ary[i]]) {
countValue[ary[i]] += 1;
} else {
countValue[ary[i]] = 1;
}
}
for (i = 0; i < len; i++) {
if (countValue[ary[i]] > 1) {
ary[i] = 0;
}
}
console.log(...ary);
Probably this is the quickest algorithm, though it will alter your original array.
const array = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
const map = {};
for (let ind = 0; ind < array.length; ind++) {
const e = array[ind];
if (map[e] === undefined) {
map[e] = ind;
} else {
array[map[e]] = 0;
array[ind] = 0;
}
}
console.log(...array);
I have an array like so: [1, 2, 3, 4, 5, 6, 7, 9, 10]. I need to chunk it into different size chunks, yet with a simple pattern of: 4, 3, 3, 3, 4, 3, 3, 3 like so:
[
[ // four
1,
2,
3,
4
],
[ // three (1/3)
5,
6,
7
],
[ // three (2/3)
8,
9,
10
],
[ // three (3/3)
11,
12,
13
],
[ // four
14,
15,
16,
17
],
[ // three (1/3)
18,
19,
20
], // and so on..
]
I have tried with this code I have customized:
const arr; // my array of values
const chuncked = arr.reduce((acc, product, i) => {
if (i % 3) {
return acc;
} else if (!didFourWayReduce) {
didFourWayReduce = true;
fourWayReduces++;
if ((fourWayReduces - 1) % 2) { // only make every second a "4 row"
return [...acc, arr.slice(i, i + 3)];
} else {
return [...acc, arr.slice(i, i + 4)];
}
} else {
didFourWayReduce = false;
return [...acc, arr.slice(i, i + 3)];
}
}, []);
And it works, almost, expect that the first chunk of threes (1/3) have the last element of the chunk with 4. So 1 key is repeated every first chunk of three. Like so:
[
[
1,
2,
3,
4
],
[
4, // this one is repeated, and it shouldn't be
5,
6
]
]
You could take two indices, one for the data array and one for sizes. Then slice the array with a given length and push the chunk to the chunks array.
Proceed until end of data.
var data = Array.from({ length: 26 }, (_, i) => i + 1),
sizes = [4, 3, 3, 3],
i = 0,
j = 0,
chunks = [];
while (i < data.length) chunks.push(data.slice(i, i += sizes[j++ % sizes.length]));
console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const arr = Array.from({ length: 100 }, (_, i) => i);
const copy = [...arr];
const sizes = [4, 3, 3, 3];
const result = [];
let i = 0;
while (i <= arr.length && copy.length) {
result.push(copy.splice(0, sizes[i % sizes.length]));
i++;
}
console.log(result);
A recursive approach is fairly elegant:
const chunks = (xs, [s, ...ss]) =>
xs.length ? [xs .slice (0, s), ... chunks (xs .slice (s), [...ss, s])] : []
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
const sizes = [4, 3, 3, 3]
console .log (chunks (data, sizes))
.as-console-wrapper { max-height: 100% !important; top: 0; }
By replacing [s, ...ss] with [...ss, s], we pass a cycled version of the sizes array, so that for instance, [4, 3, 3, 3] becomes [3, 3, 3, 4]. This makes it easy to parse step-by-step.
Mod operator to check if it should be 4 or 3. Use two arrays just to make it easier (can be done with one)
const groupIt = arr => arr.reduce(({
group,
out
}, v, i) => {
var max = out.length % 4 === 0 ? 4 : 3
group.push(v)
if (group.length === max || i === arr.length - 1) {
out.push(group)
group = []
}
return {
group,
out
}
}, {
group: [],
out: []
}).out
console.log(groupIt([1, 2, 3, 4, 5, 6, 7, 8]))
var test = (new Array(30)).fill(0).map((x,i) => i + 1)
console.log(groupIt(test))
with just one:
const groupIt = arr => arr.reduce((out, v, i) => {
var max = (out.length - 1) % 4 === 0 ? 4 : 3
out[out.length - 1].push(v)
if (out[out.length - 1].length === max) {
out.push([])
}
return out
}, [[]])
console.log(groupIt([1, 2, 3, 4, 5, 6, 7, 8]))
var test = (new Array(30)).fill(0).map((x, i) => i + 1)
console.log(groupIt(test))
This answer is similar to that of Nina Scholz, but uses a for loop, which I personally find more clear.
const arr = Array.from({length: 100}, (_, i) => i + 1);
const sizes = [4, 3, 3, 3];
const result = [];
for (let i = 0, j = 0; i < arr.length; i += sizes[j], j = (j + 1) % sizes.length) {
result.push(arr.slice(i, i + sizes[j]));
}
console.log(result);