Getting a array.push to do nothing - javascript

Trying to figure out a way that if the results of my loop equals undefined, to have my array.push do nothing. this is my code.
barcodes.sort();
var first = barcodes.slice(0, (barcodes.length + 1) / 2);
var second = barcodes.slice(((barcodes.length + 1) / 2), barcodes.length);
var result = [];
for (var i = 0; i < barcodes.length; i++) {
if (i % 2 === 0) {
result.push(first[i / 2]);
result.push(second[parseInt(i)/2]);
}else {
}
}
getting results when its odd as such: (when even is fine)
array results (12) ["1001", "9003", "3001", "9005", "3002", "9006", "3003", "9007", "9001", "9008", "9002", undefined]

result.push(second[parseInt(i)/2]);
This is undefined if you have an odd number because second.length is one less than half of barcodes. So if barcodes.length == 11, that second push is pushing second[5] when second.length == 5. This doesn't exist since indices start at 0
barcodes = ["1001", "9003", "3001", "9005", "3002", "9006", "3003", "9007", "9001", "9008", "9002"];
barcodes.sort();
var first = barcodes.slice(0, (barcodes.length + 1) / 2);
var second = barcodes.slice(((barcodes.length + 1) / 2), barcodes.length);
var result = [];
for (var i = 0; i < barcodes.length; i++) {
if (i % 2 === 0) {
result.push(first[i / 2]);
if(second[(i / 2)]) {
result.push(second[(i / 2)]);
}
}
}
console.log(result);
You could add this line: if(second[(i / 2)]) to avoid the undefined but again I'm not 100% sure what your end goal is so I'm not sure if this fully answers the question

You could take the barcode array and take an ofset for the second value for pushing.
The adjustment for the length keeps same element groups and add only at the end an undefined.
Examples:
given
barcode 0 1 2 3 4 5 6 7 8
first 0 1 2 3 4
second 5 6 7 8
result
0 5 1 6 2 7 3 8 4 undefined
given
barcode 0 1 2 3 4 5 6 7 8 9
first 0 1 2 3 4
second 5 6 7 8 9
result
0 5 1 6 2 7 3 8 4 9
var barcodes = [0, 1, 2, 3, 4, 5, 6, 7, 8],
result = [],
i,
l = (barcodes.length + 1) >> 1;
for (var i = 0; i < l; i++) {
result.push(barcodes[i], barcodes[i + l]);
}
console.log(result);

Related

Time Limit Exceeded on Leetcode: How can I optimize my code more in JavaScript?

I am trying to solve the Sliding Window Maximum question on leetcode. It's giving me Time Limit Exceeded so I guess my code isn't optimized well and needs more efficient solutions. But I tried to optimize my solution but still got Time Limit Exceeded on leetcode.
Ques1: Sliding Window Maximum
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
Return the max sliding window.
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
Constraints:
- 1 <= nums.length <= 10^5
- 10^4 <= nums[i] <= 10^4
- 1 <= k <= nums.length
Ques link
My code: Test cases 37 / 51
const nums = [1,3,-1,-3,5,3,6,7], k = 3
let arr = [];
let j = k;
for (let i = 0; i < nums.length; i++) {
if (j <= nums.length) {
let slicedArr = nums.slice(i, j);
arr.push(Math.max(...slicedArr));
j++
} else {
break;
}
}
console.log(arr);
How can I optimize my code so that it can run all test cases?

Moving objects in javascript (the start of the snake game)

Does anyone have an idea how to make these 3 colored squares move around the perimeter of the board, and not like now, i.e. in lines? (lines 57-78) https://codepen.io/diana-larussa/pen/ExgpXzo
function timer() {
ttl--
divElement = document.querySelectorAll('div')
divElement[nr_boxu].style.backgroundColor = "#6d5dfc"
divElement[nr_boxu].value = 0
nr_boxu = nr_boxu + 1
divElement[nr_boxu].style.backgroundColor = "#F25270"
divElement[nr_boxu+1].style.backgroundColor = "#F25270"
divElement[nr_boxu+2].style.backgroundColor = "#F25270"
spanTimer.innerHTML = "TIME: " + ttl
//if (nr_boxu>gridDOMElement.value-4) stop()
/*if (divElement[nr_boxu] == gridDOMElement.value - 4) {
divElement[gridDOMElement.value + 1].style.backgroundColor = "#F25270"
}*/
if (ttl == 0) stop()
}
I think for each grid size it is possible to generate perimeter sequence of indices and timer() function could pick 4 of those indices to update.
For example, in this grid 5x4:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
perimeter array would be: [0, 1, 2, 3, 4, 9, 14, 19, 18, 17, 16, 15, 10, 5] (indices highlighted in bold)
timer function will pick 4 indices out of the array, for example [0, 1, 2, 3] at the start and will colour element at index 0 with #6d5dfc and 1, 2, 3 with #F25270.
It will later follow around the perimeter, for example picking 4 elements: [2, 3, 4, 9] and colouring element 2 with #6d5dfc and 3, 4, 9 with #F25270 (need to be careful when reaching end of array).
nr_boxu seems to be incremented starting from 0 on every timer() call.
It can be used to pick 4 elements from perimeter array starting from 0 till the end of array.
The following formula - nr_boxu % perimeter.length uses remainder operator to keep iterating from 0 till perimeter.length - 1.
perimeter and timer can be built like this:
function getPerimeter(cols, rows) {
let res = [];
// top line: 0, 1, 2, 3, 4
for (let i = 0; i < cols; i++) {
res.push(i);
}
// right line: 9, 14
for (let i = 1; i < rows - 1; i++) {
res.push(cols * (i + 1) - 1);
}
// bottom line: 19, 18, 17, 16, 15
for (let i = 0; i < cols; i++) {
res.push(cols * rows - 1 - i);
}
// left line: 10, 15
for (let i = rows - 2; i > 0; i--) {
res.push(i * cols);
}
return res;
}
let perimeter = getPerimeter(numOfColumns, numOfRows);
function timer() {
ttl--
const ind1 = perimeter[nr_boxu % perimeter.length];
const ind2 = perimeter[(nr_boxu + 1) % perimeter.length];
const ind3 = perimeter[(nr_boxu + 2) % perimeter.length];
const ind4 = perimeter[(nr_boxu + 3) % perimeter.length];
divElement = document.querySelectorAll('div')
divElement[ind1].style.backgroundColor = "#6d5dfc"
divElement[ind1].value = 0
nr_boxu = nr_boxu + 1
divElement[ind2].style.backgroundColor = "#F25270"
divElement[ind3].style.backgroundColor = "#F25270"
divElement[ind4].style.backgroundColor = "#F25270"
spanTimer.innerHTML = "TIME: " + ttl
//if (nr_boxu>gridDOMElement.value-4) stop()
/*if (divElement[nr_boxu] == gridDOMElement.value - 4) {
divElement[gridDOMElement.value + 1].style.backgroundColor = "#F25270"
}*/
if (ttl == 0) stop()
}

Refining code: Is there a better way to map one (shorter) array to another (longer) array of objects in Javascript?

I have a React project that uses an array of colors for styling a few things:
export const backlightArray = [
theme.capri,
theme.aqua,
theme.oceanGreen,
theme.yellow,
'orange',
theme.lightRed
];
and another array of objects with attributes for anchor tags:
const siteStart = [
{ label: 'StackOverflow', href: 'https://stackoverflow.com' },
{ label: 'rwieruch', href: 'https://www.robinwieruch.de/blog' },
{ label: 'ITNext.io', href: 'https://itnext.io/' },
{ label: 'Dev.to', href: 'https://dev.to/' },
{
label: `ycombninator ('Hacker News')`,
href: 'https://news.ycombinator.com/'
},
{ label: 'OpenBase.io', href: 'https://openbase.io/' },
{ label: 'Coolors.co', href: 'https://coolors.co/' },
{ label: 'GitHub', href: 'https://www.github.com/' },
{ label: '/r/homelab/', href: 'https://www.reddit.com/r/homelab/' },
];
(I've shortened this for the example, but right now this array has 14 links).
The colors array is shorter than the array of site objects. I want the colors to repeat once they colors array ends, so I came up with this loop to add colors from the backlightArray for the length of the siteStart array:
let siteListColorsArray = [];
for (let i = 0; i < siteStart.length; i++) {
if (siteListColorsArray.length < siteStart.length) {
backlightArray.map(color => siteListColorsArray.push(color));
}
}
and then map those colors along with other shared attributes for the links like so:
const sites = siteStart.map((site, idx) => {
site.target = '_blank';
site.rel = 'noopener noreferrer';
site.id = `${site.label.slice(0, 3)}-${idx}`; // this is for 'key'
site.color = siteListColorsArray[idx];
return site;
});
export default sites;
I wrote it this way so I could add /remove label and href objects to/from the siteStart array and not have to mess with any other attributes in the finished objects.
It works properly, but I am just wondering: does this code look decent to other people? If you were to do something similar, what would you do differently?
I think this should do the job for you:
colorsLastIndex = backlightArray.length - 1;
const sites = siteStart.map((site, idx) => {
const newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1 : idx;
site.id = `${site.label.slice(0, 3)}-${idx}`; // this is for 'key'
site.color = backlightArray[newIndex];
return site;
});
I got a great answer that replaced this nested loop to create a longer array of colors:
let siteListColorsArray = [];
for (let i = 0; i < siteStart.length; i++) {
if (siteListColorsArray.length < siteStart.length) {
/* lengths: (0) (13) */
backlightArray.map(color => siteListColorsArray.push(color));
/* (length = 6) (iterates until > 13) */
}
}
with this ternary expression to subtract 1 from the modulus of index % backlightArray.length once the index is greater than 5 (backlightArray.length -1):
let colorsLastIndex = backlightArray.length - 1;
const sites = siteStart.map((site, idx) => {
site.id = `${site.label.slice(0, 3)}-${idx}`;
const newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1 : idx;
site.color = backlightArray[newIndex];
return site;
});
however, this solution made the newIndex return -1, resulting in a missing color value for that iteration. When I console.log(newIndex), you can see that the number goes below 0 and does not return to 5 - I wrote out the steps to illustrate (I performed the calculations in the console to verify):
/* start first iteration w/ index */
0
1
2
3
4
5
/* start newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1
(6) (6) (6) (5) (- 1) */
0 // 6 % 5 - 1
1 // 7 % 5 - 1
2 // 8 % 5 - 1
3 // 9 % 5 - 1
-1 // 10 % 5 - 1
0 // 11 % 5 - 1
1 // 12 % 5 - 1
2 // 13 % 5 - 1
Here's the solution that worked for me (note: backlightArray.length = 6):
const newIndex = idx >= backlightArray.length ? idx % backlightArray.length : idx;
site.color = backlightArray[newIndex];
console.log(newIndex):
/* start first iteration w/ idx */
0
1
2
3
4
5
/* start newIndex = (idx) >= backlightArray.length ? idx % backlightArray.length
(6) (6) (6) % (6) */
0 // 6 % 6
1 // 7 % 6
2 // 8 % 6
3 // 9 % 6
4 // 10 % 6
5 // 11 % 6
0 // 12 % 6
1 // 13 % 6
Once the index gets to 6, which is 1 above 5 (the last color in backlightArray), 6 = backlightArray.length, and the condition becomes true. Then, the remainder of index divided by 6 equals 0, and increases by one thereafter until the index reaches another factor of 6 (e.g. 12), at which point it becomes 0 again. This condition also works:
newIndex = idx + 1 > backlightArray.length ? idx % backlightArray.length : idx;
idx + 1 might be a little more illustrative of the logic.
This is a great pattern that reduces the need for unwieldy-looking nested loops. Thanks so much for sharing!

Combination Algorithm without sort()

I need results starting from the beginning with 123 as shown below. I want to print from the beginning without sort().
1 2 3
1 2 4
1 2 5
.....
3 5 6
4 5 6
But, The results are shown below.
4 5 6
3 5 6
2 5 6
1 5 6
3 4 6
2 4 6
1 4 6
2 3 6
1 3 6
1 2 6
3 4 5
2 4 5
1 4 5
2 3 5
1 3 5
1 2 5
2 3 4
1 3 4
1 2 4
1 2 3
result = "";
var N = 6;
var M = 3;
var arr = new Array(M);
combi(N, M, arr, M);
alert(result);
function combi(n, r, arr, sz) {
var i = n + 1;
while (i-- > r) {
// choose the first element
arr[r - 1] = i;
if (r > 1) { // if still needs to choose
// recursive into smaller problem
combi(i - 1, r - 1, arr, sz);
} else {
// print out one solution
var j = -1;
while (++j < sz) {
result += arr[j] + " ";
}
result += "\n";
}
}
}
Beside the inverting of all, you could start with one and iterat until the wanted value.
function combination(n, r) {
function iter(i, temp) {
if (temp.length === r) { // set complete
result.push(temp.join(' ')); // join values
return;
}
if (i + r > n + 1 + temp.length) { // exit early
return;
}
iter(i + 1, temp.concat(i)); // take the value
iter(i + 1, temp); // go without the value
}
var result = []; // result set
iter(1, []); // start with 1 and
return result; // empty array for collecting sets
}
console.log(combination(6, 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can revert the order by changing your code this way:
function combi(n, r, arr, sz) {
var i = r - 1;
while (i++ < n) {
// choose the first element
arr[r - 1] = i;
if (r > 1) { // if still needs to choose
// recursive into smaller problem
combi(i - 1, r - 1, arr, sz);
} else {
// print out one solution
var j = -1;
while (++j < sz) {
result += arr[j] + " ";
}
result += "\n";
}
}
}

jQuery for loop every third

Why is it only every third when I change i = 0 to i = 1 but then I don't get all results.
$.getJSON('search.php', {q: query, ajax: 'true'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
if(i % 3 == 0) {
// every third
} else {
}
$("#profile-search-results").html(options);
}
});
I think what are trying to do is to get elements at indexes 3, 6, 9... etc but your condition is executed for first, fifth, eighth... etc elements.
The problem is your loop is starting with 0, so 0%3 will return 0... since the element index in jQuery starts with 0, what you need is elements at indexes 2, 5, 8,... etc. So you should check for reminder 3 == 2
for (var i = 0; i < j.length; i++) {
if (i % 3 == 2) {
// every third
} else {
}
% is modulo operator.
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
7 % 3 = 1
...
So what you have is normal.

Categories

Resources