Why same output for both the cases? - javascript

I created two different variables a and b and in first for loop, I placed a.push and then a.unshift and in second for loop, I placed b.unshift first and then b.push but why the both variables (a and b) output will be same as [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let a = [];
for(let i=0 ; i <=10 ; i++) {
a.push(i);
a.unshift(i);
}
console.log(a);
let b = [];
for(let j=0 ; j <=10 ; j++) {
b.unshift(j);
b.push(j);
}
console.log(b);

The push() method adds one or more elements to the end of an array and returns the new length of the array.
The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array.
First one always works on the end, second one on the beginning. So it doesn't matter if you call first unshift() or push() because they do the same action every time. It's like adding. It doesn't matter if you do 3 + 5 or 5 + 3. Theoretically, it do the same in the opposite order, but because it uses the same value the result is the same.
Try
let a = [];
for(let i=0 ; i <=10 ; i++) {
a.push(i + 1);
a.unshift(i);
}
console.log(a);
let b = [];
for(let j=0 ; j <=10 ; j++) {
b.unshift(j + 1);
b.push(j);
}
console.log(b);
The result is different.

Related

Javascript for loop and splice function

Good day, I have been trying to solve JS problem where I have an array a = [1, 1, 1, 2, 1, 3, 4]. I have to loop through an array and remove every three elements ie (1,1,1) do some logic, then the next three (1,1,2), and so on.
I have used for loop and splice
a = [1, 1, 1, 2, 1, 3, 4]
tuple = ()
for(j=0; j < a.length; j++){
tuple = a.splice(j, 3)
}
However, loop would not go beyond first round of (1,1,1).
What would be the correct way to loop through this array and remove sets of every three elements.
thank you.
Splice return removed elements from base array in given range. You probable want to use slice which only copy them and doesn't change primary array. You can also check this solution.
let a = [1, 1, 1, 2, 1, 3, 4];
for (j = 0; j < a.length; j++) {
if ( j < a.length - 2 ) {
const touple = [ a[j], a[j+1], a[j+2] ]
console.log( touple )
}
}
splice changes the original array and that must be causing your issue.
So, you can use slice which returns a shallow copy of a portion of the original array (without modifying the original array):
const a = [1, 1, 1, 2, 1, 3, 4]
const doLogic = (arr) => {
console.log(JSON.stringify(arr)) // JSON.stringify is only for one-liner print. You can ignore it.
}
for (let i = 0; i < a.length - 2; i++) {
const picked = a.slice(i, i + 3)
doLogic(picked)
}
Or this, if you want to pick the full array when length is less than 3:
if (a.length < 3) {
doLogic(a)
} else {
for (let i = 0; i < a.length - 2; i++) {
const picked = a.slice(i, i + 3)
doLogic(picked)
}
}

Javascript loop an array to find numbers divisible by 3

I am needing to find the correct way to have javascript loop through an array, find all numbers that are divisible by 3, and push those numbers into a new array.
Here is what I have so far..
var array = [],
threes = [];
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
threes = array.push(i % 3);
}
return threes;
}
So if we pass through an array of [1, 2, 3, 4, 5, 6] through the function, it would push out the numbers 3 and 6 into the "threes" array. Hopefully this makes sense.
You can use Array#filter for this task.
filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value or a value that coerces to true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.
function loveTheThrees(array) {
return array.filter(function (a) {
return !(a % 3);
});
}
document.write('<pre>' + JSON.stringify(loveTheThrees([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 0, 4) + '</pre>');
console.log([1, 2, 3, 4, 5, 6, 7].filter(function(a){return a%3===0;}));
Array.filter() iterates over array and move current object to another array if callback returns true. In this case I have written a callback which returns true if it is divisible by three so only those items will be added to different array
var array = [],
three = [];
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
if(array[i] % 3 == 0){
three.push(array[i]);
}
}
return three;
}
Using Filter like suggested by Nina is defiantly the better way to do this. However Im assuming you are a beginner and may not understand callbacks yet, In this case this function will work:
function loveTheThrees(collection){
var newArray = []
for (var i =0; i< collection.length;i++){
if (myArray[i] % 3 === 0){
newArray.push(collection[i])
}
}
return newArray;
}
loveTheThrees=(arr)=>arr.filter(el=>Boolean(parseFloat(el)) && isFinite(el) && !Boolean(el%3))
es6 version + skipping non numbers
loveTheThrees([null,undefined,'haha',100,3,6])
Result: [3,6]
Check if the number is divisible by 3 if so then add it to array. Try this
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
if(array[i] % 3 == 0){
three.push(array[I]);
}
}
var originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function loveTheThrees(array1) {
var threes = [];
for (var i = 0; i < array1.length; i++) {
if (array1[i] % 3 === 0) {
threes.push(array1[i]);
}
}
return threes;
}
loveTheThrees(originalArray);
In ES6:
const arr = [1, 33, 54, 30, 11, 203, 323, 100, 9];
// This single line function allow you to do it:
const isDivisibleBy3 = arr => arr.filter(val => val % 3 == 0);
console.log(isDivisibleBy3(arr));
// The console output is [ 33, 54, 30, 9 ]

Understanding nested for loops in javascript

I'm learning JavaScript at the moment on freecodecamp and they have an example for nested for loops in one of their excercises:
var arr = [[1,2], [3,4], [5,6]];
for (var i=0; i < arr.length; i++) {
for (var j=0; j < arr[i].length; j++) {
console.log(arr[i][j]);
}
}
With console.log = 1 2 3 4 5 6 undefined.
I understand for loops more or less, and I understand that [i] and [j] are used to access the array (I think?). I just don't understand why at the end it just prints out those numbers? I found this question asked a few years back but it just explains how to write them, not how they work:
For loop in multidimensional javascript array
I broke it down into:
var arr = [ [1,2], [3,4], [5,6]];for (var i=0; i < arr.length; i++) {
console.log(arr[i]);}
Which prints out
[ 1, 2 ]
[ 3, 4 ]
[ 5, 6 ]
undefined
and
var arr = [ [1,2], [3,4], [5,6]];
for (var i=0; i < arr.length; i++) {
for (var j=0; j < arr[i].length; j++) {
console.log(arr[i]); }}
which prints out:
[ 1, 2 ]
[ 1, 2 ]
[ 3, 4 ]
[ 3, 4 ]
[ 5, 6 ]
[ 5, 6 ]
undefined
and
var arr = [ [1,2], [3,4], [5,6]];
for (var i=0; i < arr.length; i++) {
for (var j=0; j < arr[i].length; j++) {
console.log(arr[j]); }}
which prints out
[ 1, 2 ]
[ 3, 4 ]
[ 1, 2 ]
[ 3, 4 ]
[ 1, 2 ]
[ 3, 4 ]
undefined
I understand the first two arr[i]. The loop iterates through the array and prints out the individual elements (in this case an array) and in the second one I guess it just does it twice because there are two loops. What I don't understand is:
why the last array in arr[j] is not printed out (where did the
[5, 6] go?)
why arr[i][j] suddenly eliminates the arrays and just
prints out the numbers
where the 'undefined' comes from
Could anyone help me out with this and explain the steps the code takes before printing it out in the console? I would really like to understand it but don't even know how to search for this question the right way.
var arr = [[1,2], [3,4], [5,6]];
This is an array of arrays. It is a little bit easier to read like this:
var arr = [
[1,2],
[3,4],
[5,6]
];
That makes it a little bit easier to see that you have an array of 3 arrays. The outer 'for' will loop through each of 1st level arrays. So the very first outer for loop when i=0 you are going to grab the first inner array [1,2]:
for (var i=0; i < arr.length; i++) {
//First time through i=0 so arr[i]=[1,2];
}
In the inner loop you are going to loop through each of the 3 inner arrays one at a time.
for (var j=0; j < arr[i].length; j++) {
//Handle inner array.
}
This argument grabs the length of the inner array:
arr[i].length
So on your first time through the outer loop i=0 and arr[i] is going to equal [1,2] because you are grabbing the 0th element. Remember, arrays elements are always counted starting at 0, not 1.
Finally you are printing out the results with:
console.log(arr[i][j]);
The first time through you can break it down a little. i=0 and j=0. arr[0][0] which translates as grab the first element from the outer array and then the first element from the first inner array. In this case it is '1':
[
[1,2], <-- 0
[3,4], <-- 1
[5,6] <-- 2
];
The code will loop through the first first set [1,2], then the second [3,4], and so on.
The double for loop you have above works like so:
var arr = [[1,2], [3,4], [5,6]];
for (var i=0; i < arr.length; i++) {
// i = 0, then we loop below:
for (var j=0; j < arr[i].length; j++) {
//here we loop through the array which is in the main array
//in the first case, i = 0, j = 1, then we loop again, i = 0, j = 1
console.log(arr[i][j]);
//after we finish the stuff in the 'j' loop we go back to the 'i' loop
//and here i = 1, then we go down again, i, remains at 1, and j = 0, then j = 1
//....rinse and repeat,
}
}
In plain english:
We grab the first element in the main array, which is an array itself,
we loop through that, and log at each index, this is terminated by our length condition in the second loop. We then move to to the next index of the main array, which is an array itself.... and so on, until we reach the end of the main array
To access and index in the main array, we need to use array[i] - that index holds an array - so to go INTO that array, we need to use array[i][j]
Hope that makes sense!
Despite some caveats of using for-in loops on arrays, they can imo sometimes help to clear the mess in nested loops a bit:
var arr = [[1,2], [3,4],[5,6]];
for (i in arr){
for (j in arr[i]){
console.log(arr[i][j]);
}
}
Also code visualization can clarify execution!
I know this is an old question... But because this is a popular post from ye olde google search, I feel it's helpful to add a way to visualize what's going on in nested for-loops.
As a JS teacher, I've found this method super helpful for visually-oriented people and those w/ dyslexia and related things).
// Original: https://repl.it/#justsml/nested-loop-visualizations
var nums = [[1,2,3], [4,5,6], [7,8,9]];
console.log('Example w/ Numbers:\n');
console.log('The array data: ', JSON.stringify(nums));
for (var i=0; i < nums.length; i++) {
// Main/"top" array - accessing via "arr[i]"
for (var j=0; j < nums[i].length; j++) {
// here we loop through the "child" arrays
let helpfulLabel = `nums[${i}][${j}]`
let value = nums[i][j]
console.log(helpfulLabel, 'Value=' + value);
}
}
console.log('\nExample w/ String Data:\n');
var letters = [['a', 'b', 'c'], ['d', 'e', 'f'], ['x', 'y', 'z']];
console.log('The array data: ', JSON.stringify(letters));
for (var i=0; i < letters.length; i++) {
for (var j=0; j < letters[i].length; j++) {
let helpfulLabel = `letters[${i}][${j}]`
let value = letters[i][j]
console.log(helpfulLabel, 'Value=' + value);
}
}
Preview of Results
function multiplyAll(arr) {
var product = 1;
// Only change code below this line
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
console.log(product)
}
}
// Only change code above this line
return product;
}
// Modify values below to test your code
multiplyAll([[1], [2], [3]])
//multiplyAll([[1, 2], [3, 4], [5, 6, 7]]);
//multiplyAll([[5, 1], [0.2, 4, 0.5], [3, 9]])
why the last array in arr[j] is not printed out (where did the [5,
6] go?)
You may notice that if you print out j as console.log(j), it will
print 6 times as 0, 1, 0, 1, 0, 1. And what you're trying to print
is arr[j] which [5, 6] will not be displayed because its on
arr[2]
why arr[i][j] suddenly eliminates the arrays and just prints out the numbers
As you state there, arr is an array of 3 arrays. arr[i] represents
3 arrays either of [1, 2], [3, 4] or [5, 6]. And the j in
arr[i][j] represents the index of those 3 arrays. This is called
Multidimensional Array. arr[i][j] does not eliminate the array, but It selects the value in the index of j inside arr[i].
where the 'undefined' comes from
It's just chrome thingy when you use console.log. Chrome returns
undefined whenever you try to do that. Try to do it on firefox and you
will see it no longer.
function multiply(arr) {
var product = 1;
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
product *= arr[i][j];
}
}
return product;
}

Can anyone tell me why this loop isn't working as it should?

This is for an exercise on codewars.com. The idea is to make a function that takes an array as the first parameter, then deletes each item in sequence defined by the second parameter, so if the second parameter is 3, it'll delete 3 first(counting for this one is supposed to be 1 based, not 0 based), then 6, then 9, then back around to 2, as though all the items were in a circle, then 7 (because 3 and 6 are gone), etc, then return the items in the order in which they were deleted (this pattern is referred to as a Josephus permutation).
So here's my code:
function josephus(items, k) {
var arr = [];
var l = items.length;
var a = k - 1;
for (var i = 0; i < l; i++) {
arr.push(items[a]);
items.splice(a, 1);
a += k - 1 ;
if (a >= items.length) { a = a - items.length; }
}
return arr;
}
It works sometimes. It worked right with josephus([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1), but then with josephus([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2), it worked until the last number(5, in this case), then returned null. In fact, most times, it returns null in the place of the last item. Can anyone tell me why it's doing this? If you have a codewars account, you can try it out in its context here: http://www.codewars.com/kata/5550d638a99ddb113e0000a2/train/javascript
Your index re-calculation isn't working. i.e. a = 3, items = [1] a becomes 2, items[2] is undefined. Try this code:
function j(items,k){
var arr = [];
var l = items.length;
var a = k - 1;
for(var i = 0; i<l; i++){
arr.push(items[a]);
items.splice(a, 1);
a += k - 1 ;
a = a % items.length;
}
return arr;
}
Replace
arr.push(items[a]);
with
arr.push(items[a%items.length]);

Filtering arrays of complex objects with loops

I have two arrays of complex nexted objects that I'm looking for qualifying values within using loops and if statements as seen below. When I find a qualifying object, I need to filter that object out during the next go around of the loop. I'm trying to do that with an array as you can see here but it isn't working as the array starts over during each iteration of the loop. The following version is a simplified version of my code.
I want to update the values in array2 based on the if statement so that those values are not repeated in the nested loop. Instead my emptyArray remains empty instead of adding values from the array2 as elements of array2 are equal to elements of array.
To be clear, right now emptyArray remains empty and never filters array2. I'd like to see emptyArray collect value 2 at the start of the outer loop's second iteration then I'd like to see emptyArray collect value 4 at the start of the 4th iteration of the outer loop.
I'd want to filter each of these values from array2 as they become part of emptyArray so that they do not set off the if statement during the 6th and 8th iterations of the outer loop. I imagine that emptyArray = [2, 4] and array2 = [6, 8, 10] when the loops are finished.
Bottom line, I need emptyArray to collect the qualifying values and pass them back to var array2 for filtering as the loop processes. Remember this is a simplified version of the arrays, and underscore based solution would be very complicated for me to implement or for you to successfully suggest without much more detail.
My code:
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (i = 0; i < array.length; i++){
var something = array[i];
var array2 = _.without(array2, emptyArray);
for (a = 0; a < array2.length; a++){
var value = array2[a];
if(something === value){
emptyArray.push(value);
break;
}
}
}
There are a few things wrong with your code, but the reason why you think that push isn't working is because you are overriding your array2 inside the loop.
The push never gets called because your for loop sees an empty array2 when you are doing var array2 = _.without(array2, emptyArray);
Basically var array2 = _.without(array2 /* this is empty, you just overrode it in this scope */, emptyArray); will always result in an empty array and your for loop will exit because length is array2.length === 0 from the start.
Also, you want to use _.difference instead of _.without
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (var i = 0; i < array.length; i++) {
var something = array[i];
array2 = _.difference(array2, emptyArray);
for (var j = 0; j < array2.length; j++) {
var value = array2[j];
if (something === value) {
emptyArray.push(value);
break;
}
}
}
console.log("array2",array2);
console.log("emptyArray", emptyArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.js"></script>
array2 [6, 8, 10]
emptyArray [2, 4]
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (var i = 0; i < array.length; i++) {
var something = array[i];
for (var j = 0; j < array2.length; j++) {
var value = array2[j];
if (something === value) {
array2 = _.without(array2, value);
break;
}
}
}

Categories

Resources