Create a function to splice without using any built-in JavaScript methods - javascript

The code is working fine for all the test cases. Is it possible to reduce the number of lines of code or reduce the number of for loops?
const arr_splice = (arr, startIndex = 0, deleteCount = arr.length, ...insertElems) => {
// [1, 2, 3, 4, 5, 6]
for (let i = startIndex; i < arr.length; i++) {
arr[i] = arr[i + deleteCount]
}
// [ 1, 2, 5, 6, undefined, undefined ]
while (arr[arr.length - 1] == undefined && arr.length > 0) {
arr.length--
}
// [ 1, 2, 5, 6 ]
for (let i = arr.length - 1; i >= startIndex; i--) {
arr[i + insertElems.length] = arr[i]
}
// [ 1, 2, 5, 6, <2 empty items>, 5, 6 ]
for (let i = startIndex, j = 0; j < insertElems.length; j++, i++) {
arr[i] = insertElems[j]
}
// [1, 2, 10, 20, 30, 40, 5, 6]
return arr;
}
let result = arr_splice([1, 2, 3, 4, 5, 6], 2, 2, 10, 20, 30, 40);
console.log(result);//[1, 2, 10, 20, 30, 40, 5, 6]
//cross check
let arr=[1, 2, 3, 4, 5, 6]
arr.splice(2,2,10, 20, 30, 40)
console.log(arr);

Related

split chunk array from bigger array

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);

Delete all elements from an array A which are present in an array B without using a double loop

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) )

JavaScript looping issue in the middle of looping

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);

JavaScript: Change all repeated values to 0 in array

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);

Split array into different size chunks (4, 3, 3, 3, 4, 3, 3, 3, etc)

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);

Categories