I'm learning for loops in JS and am trying to learn how to console.log the first and last element in an array on one iteration, then console.log the second and second to last elements, etc.
here's what I have tried:
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[i-1];
}
This is printing elements from my array, but not in the correct order
So what you are trying to achieve is to print the last element, the second last element, etc...
You can use the myArray.length property to do it, just substract the iterator + 1 to the array length and obtain the result you want.
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[myArray.length - (i + 1)]);
}
The (i + 1) is because the .length property returns the number of item of the array, but not the maximum index of the array. So if the length of the array is 5, the maximum index of the array is 4 (since index starts from 0). You can also write it like: myArray[myArray.length - i - 1]
Here an example:
const myArray = [1, 2, 3, 4, 5];
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[myArray.length - (i + 1)]);
}
Create a temporary copy of your array, then use shift (to remove the head element) and pop (to remove the tail element) until the copy is empty:
const realArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const temporary = realArray.slice();
while (temporary.length) {
const e1 = temporary.shift();
// do something with e1
console.log(e1);
const e2 = temporary.pop();
if (e2) {
// note that e2 _might not exist_ so: always test
console.log(e2);
}
}
You can use two counters that works on opposite direction
i will move forward with increment as i++.
j will move backward with decrement as j--.
If there are even numbers of elements in an array then you should print both numbers arr[i] and arr[j]. But be sure to handle the odd number of elemetns in an array then you have to print either of arr[i] or arr[j]
function print(arr) {
let i = 0;
j = arr.length - 1;
while (i <= j) {
if (i !== j) {
console.log(arr[i], arr[j]);
} else console.log(arr[j]);
i++;
j--;
}
}
print([1, 2, 3, 4, 5, 6, 7, 8]);
print([1, 2, 3, 4, 5, 6, 7, 8, 9]);
Here's one way to do it, reverse the array and use the same index. Since array.reverse() mutates the original array, we slice() it in order to use a copy.
let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array.forEach((a, i) => {
let b = array.slice().reverse()[i]
if (i < array.length / 2) console.log(a, b)
})
let output = '';
for (let i = 0; i < (myArr.length) /2; i++){
output += myArr[i] + myArr[myArr.length-1-i];
}
console.log(output)
Just check for i === 0 to indicate the start of the loop and hence, you can print the last element of array
const myArray = ['first', 1, 2, 3, 'last'];
for (let i = 0; i < myArray.length - 1; i++) {
console.log(myArray[i]);
if (i === 0) {
console.log(myArray[myArray.length - 1]);
}
}
Related
Have the function ArrayChallenge(arr) take the array of integers stored in arr, and determine if any two numbers (excluding the first element) in the array can sum up to the first element in the array. For example: if arr is [7, 3, 5, 2, -4, 8, 11], then there are actually two pairs that sum to the number 7: [5, 2] and [-4, 11]. Your program should return all pairs, with the numbers separated by a comma, in the order the first number appears in the array. Pairs should be separated by a space. So for the example above, your program would return: 5,2 -4,11
If there are no two numbers that sum to the first element in the array, return -1
Input: [17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7]
Output: 6,11 10,7 15,2
Final Output: --6--,--1----1-- --1--0,7 --1----5--,2
Input: [7, 6, 4, 1, 7, -2, 3, 12]
Output: 6,1 4,3
Final Output: --6--,--1-- 4,3
My approach
function ArrayChallenge(arr) {
var sum = []
for (var i = 0; i < arr.length; i++){
for (var j = i + 1; j < arr.length; j++){
if(arr.[i] + arr[j]=== )
}
}
// code goes here
return arr;
}
// keep this function call here
console.log(ArrayChallenge(readline()));
Can you please help me with this ?
Logic
Loop through the array.
Start from index 1 to last node (except index 0) in the outer loop.
Srart from one node next to the outer loop in the inner loop.
Check the sum of both nodes.
If the sum value is same as the node at first index, push that to sum array in required format.
Check the length of sum array. If length > 0 the join sum array and return. Else return -1
Working Code
const input = [17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7];
const input2 = [7, 6, 4, 1, 7, -2, 3, 12];
const input3 = [37, 6, 4, 1, 7, -2, 3, 12];
function ArrayChallenge(arr) {
var sum = []
for (var i = 1; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] === arr[0]) {
sum.push([arr[i], arr[j]].join());
}
}
}
return sum.length > 0 ? sum.join(" ") : -1;
}
console.log(ArrayChallenge(input));
console.log(ArrayChallenge(input2));
console.log(ArrayChallenge(input3));
Your approach uses a O(n^2) level complexity. This can be solved using O(n) if you're willing so sacrifice a little on space complexity.
What you can do is :
Make an empty object.
store all values of the array (not the 0th element) in the object as key and add it's value as true.
Loop the array (from 1st index). Take the value and subtract it from the 0th element. find this subtracted value from the object, If it does not return undefined, make a pair and save it.
One drawback of this method is, you'll find duplicate entries in the result.
This Approach uses O(n) Time complexity and O(n) space complexity
function ArrayChallange(arr) {
let numObj = {}
let i = 1
let result = []
let tempVal
// Pushing all elements of arr (from index 1) inside numObj
while(i<arr.length){
numObj[arr[i]] = true
}
i = 1
// Looping the array to find pairs
while(i < arr.length){
tempVal = numObj[Math.abs(arr[0] - arr[i])]
if(tempVal){
result.push(arr[i].toString() +","+tempVal.toString())
}
}
if(result.length !== 0)
return result.join(" ")
else
return -1
}
You could use a reducer followed by a forEach loop in order to push the pairs to an empty array, then join them at the end.
const ArrayChallenge = (nums) => {
const pairs = []
// Get the first and remove it from the array
const first = nums.splice(0, 1)[0]
nums.reduce((all, curr) => {
all.forEach((a) => {
// Check if we have a match
if (curr + a === first) {
// check if it's already in the array
// we don't want duplicates
if (pairs.indexOf(`${a},${curr}`) === -1 && pairs.indexOf(`${curr},${a}`) === -1) {
// push the pair to the array separated by a space
pairs.push(`${curr},${a}`)
}
}
})
return all
}, nums) // we pass in nums as the starting point
// If there are no pairs then return -1
if (pairs.length === 0) {
return -1
} else {
// Join the pairs together with a space
const result = pairs.join(' ')
// Replace each digit (\d) with hyphens before and after
const parsed = result.replace(/(\d)/g, '--$1--')
return parsed
}
}
const result1 = ArrayChallenge([17, 4, 5, 6, 10, 11, 4, -3, -5, 3, 15, 2, 7])
console.log(result1)
const result2 = ArrayChallenge([7, 6, 4, 1, 7, -2, 3, 12])
console.log(result2)
I just got started with writing sorting algorithms.
Currently I am learning the Bubble Sort algorithm, I found the following online and it's working fine:
const arr = [3, 2, 6, 9, 3, 5];
const bubbleSort = array => {
do {
var isSorted = true;
for (var i = 0; i < array.length; i++) {
if (array[i] > array[i + 1]) {
var temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
isSorted = false;
}
}
} while(!isSorted)
return array
};
Output:
[ 2, 3, 3, 5, 6, 9 ]
However, when I try to write it using an if statement instead of a while loop like the following, it doesn't work as expected:
const arr = [3, 2, 6, 9, 3, 5];
const bubbleSort = (array) => {
let isSorted = false;
if(!isSorted) {
isSorted = true;
for(var i = 0; i < array.length; i++) {
if (array[i] > array[i + 1]) {
var temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
isSorted = false;
}
}
}
return array;
}
Output:
[ 2, 3, 6, 3, 5, 9 ]
What am I doing wrong here?
We need the while loop for bubble sort.
If we remove while then we will 'bubble' only once through the whole array. For example if the
[3, 2, 6, 9, 3, 5];
here 3 (first element) is larger than 2 (second element) so we swap them and now we have
[2, 3, 6, 9, 3, 5]
When we continue with the for loop we approach 3 (6th element) that is smaller so we swap it with 9 (5th element). AND continue forward.
[2, 3, 6, 3, 9, 5]
from here we will only go up but we can analyse the situation. We can see that 3 (4th element) is smaller than 6(third element) but the for loop is way ahead so we will not be in a situation where we swap it with a larger element.
So we have to start "bubbling" again from the beginning and we need to do it until everything is sorted. This will happen when there are nothing to swap, because we set isSorted=false when ever we swap. After array is sorted we will do a last pass where we will check every adjacent pair and if they are all sorted the swap will not occur and isSorted will be true
TLDR; we need while because 'bubbling' might need several passes through the array.
while loop is an easy way to implement Bubble Sort, otherwise you will need O(n²) algorithm with nested for loops instead, if else statements will not work:
const arr = [3, 2, 6, 9, 3, 5];
const bubbleSort = array => {
var length = array.length;
//Number of passes
for (var i = 0; i < length; i++) {
//Notice that j < (length - i)
for (var j = 0; j < (length - i - 1); j++) {
//Compare the adjacent positions
if(array[j] > array[j+1]) {
//Swap the numbers
var tmp = array[j]; //Temporary variable to hold the current number
array[j] = array[j+1]; //Replace current number with adjacent number
array[j+1] = tmp; //Replace adjacent number with current number
}
}
}
return array
}
bubbleSort(arr)
// expected output: [2, 3, 3, 5, 6, 9]
You can also see Bubble Sort pseudocode here: Bubble Sort Algorithm
I have following problem:
// Reverse Array
Write a function that accepts an array and reverses that array in place. The behavior should mimic the behavior of the native .reverse() array method. However, your reverse function should accept the array to operate on as an argument, rather than being invoked as a method on that array.
Do not use the native .reverse() method in your own implementation.
I tried the following code:
let myArray = [1, 2, 3, 4];
function reverse(myArray) {
let newArray = [];
// pop all of elements from roginal array, and store in new array
for (i=myArray.length-1; i>=0; i--){
newArray.push(myArray[i])
console.log(newArray)
}
while (newArray.length){
myArray.unshift(newArray)
}
return myArray;
}
reverse(myArray);
console.log(myArray) // expected output is [4, 3, 2, 1]
My code just keeps running and no console.log output is produced. Notice I want the reverse done to the input array argument.
What am I doing wrong? Also, what does while (newArray.length) mean / what is it doing conceptually?
Not sure why you need the unshift you can just iterate and return the array where you are pushing the value
let myArray = [1, 2, 3, 4];
function reverse(myArray) {
let newArray = [];
for (i = myArray.length - 1; i >= 0; i--) {
newArray.push(myArray[i])
}
return newArray;
}
console.log(reverse(myArray))
You can iterate the array 'till the middle, and switch between the current (i) and the opposite (length - i - 1):
const myArray = [1, 2, 3, 4];
function reverse(myArray) {
const length = myArray.length;
const middle = Math.floor(length / 2);
for(let i = 0; i < middle; i++) {
let tmp = myArray[i];
myArray[i] = myArray[length - i - 1];
myArray[length - i - 1] = tmp;
}
}
reverse(myArray);
console.log(myArray) // expected output is [4, 3, 2, 1]
You can swap first and last element in an array and iteratively swap the next and prev respectively.
You don't have to visit the complete set in the loop, get the middle element and rotate the index around that
function reverseInArray(arr){
let len = arr.length;
let temp;
for(let i=0; i < len/2; i++){
temp = arr[i];
arr[i] = arr[len - i - 1];
arr[len - i - 1] = temp;
}
return arr;
}
console.log(reverseInArray([1,2,3,4,5]));
You could swap the first and the last element and start from the most inner item.
function reverse(array) {
var i = array.length >> 1, // take half of the length as integer
l = array.length - 1; // last index value to calculate the other side
while (i--) [array[i], array[l - i]] = [array[l - i], array[i]];
}
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverse(a);
console.log(...a);
Just swap pairs starting at either end of the array, until there's none left:
function reverse(a) {
for (let i = 0, j = a.length - 1; i < j; ++i, --j) {
let tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a; // not required, but allows use in an expression
}
In ES2016 you can use destructuring assignments to perform the swap in one operation without the use of a temporary variable:
function reverse(a) {
for (let i = 0, j = a.length - 1; i < j; ++i, --j) {
[ a[j], a[i] ] = [ a[i], a[j] ];
}
return a;
}
Here:
while (newArray.length){
myArray.unshift(newArray)
}
You're adding to myArray, but not taking from newArray, hence infinite loop. Methinks it should be myArray.unshift(newArray.pop()).
A beginner JS question.. I need to write a function that reverses an array that goes as a function's input. (I cannot use a reverse method).
I wonder why this works:
function reverseArrayInPlace(array) {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
let old = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = old;
}
return array;
}
let arr = [0, 1, 2, 3, 4, 5];
console.log(reverseArrayInPlace(arr))
But this does NOT:
function reverseArrayInPlace(arr) {
let len = arr.length;
for (counter = 0; counter < 2 * len; counter += 2) {
arr.unshift(arr[counter]);
}
arr = arr.slice(0, len);
}
let b = [0, 1, 2, 3, 4, 5];
console.log(reverseArrayInPlace(b));
Looks like arr = arr.slice(0,len); part is not working..I wonder why when:
b = b.slice(0,6);
[5, 4, 3, 2, 1, 0]
If you want to change the input arrray, avoiding return, use splice:
function reverseArrayInPlace(arr) {
let len = arr.length;
for (counter = 0; counter < 2 * len; counter += 2) {
arr.unshift(arr[counter]);
}
arr.splice(len);
}
var b = [0, 1, 2, 3, 4, 5];
reverseArrayInPlace(b);
console.log(b);
EDIT:
If you want to do something like:
console.log(reverseArrayInPlace(b));
your function MUST return something, otherwise the print will always be undefined, even if b has been reverted
arr = arr.slice(0, len);
slice returns a new array which you store inside the local variable arr, that does not change b, which is still pointing to the whole array. To mutate the array you could:
arr.splice(len, len);
and then you have to return arr to log something meaningful.
Because the array is passed to the function by copying the reference, hence you cannot change the external reference from inside the function.
I need to find first two numbers and show index like:
var arrWithNumbers = [2,5,5,2,3,5,1,2,4];
so the first repeated number is 2 so the variable firstIndex should have value 0. I must use for loop.
var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
var firstIndex
for (i = numbers[0]; i <= numbers.length; i++) {
firstIndex = numbers[0]
if (numbers[i] == firstIndex) {
console.log(firstIndex);
break;
}
}
You can use Array#indexOf method with the fromIndex argument.
var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
// iterate upto the element just before the last
for (var i = 0; i < numbers.length - 1; i++) {
// check the index of next element
if (numbers.indexOf(numbers[i], i + 1) > -1) {
// if element present log data and break the loop
console.log("index:", i, "value: ", numbers[i]);
break;
}
}
UPDATE : Use an object to refer the index of element would make it far better.
var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11],
ref = {};
// iterate over the array
for (var i = 0; i < numbers.length; i++) {
// check value already defined or not
if (numbers[i] in ref) {
// if defined then log data and brek loop
console.log("index:", ref[numbers[i]], "value: ", numbers[i]);
break;
}
// define the reference of the index
ref[numbers[i]] = i;
}
Many good answers.. One might also do this job quite functionally and efficiently as follows;
var arr = [2,5,5,2,3,5,1,2,4],
frei = arr.findIndex((e,i,a) => a.slice(i+1).some(n => e === n)); // first repeating element index
console.log(frei)
If might turn out to be efficient since both .findIndex() and .some() functions will terminate as soon as the conditions are met.
You could use two for loops an check every value against each value. If a duplicate value is found, the iteration stops.
This proposal uses a labeled statement for breaking the outer loop.
var numbers = [1, 3, 6, 7, 5, 7, 6, 6, 4, 9, 10, 2, 11],
i, j;
outer: for (i = 0; i < numbers.length - 1; i++) {
for (j = i + 1; j < numbers.length; j++) {
if (numbers[i] === numbers[j]) {
console.log('found', numbers[i], 'at index', i, 'and', j);
break outer;
}
}
}
Move through each item and find if same item is found on different index, if so, it's duplicate and just save it to duplicate variable and break cycle
var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
var duplicate = null;
for (var i = 0; i < numbers.length; i++) {
if (numbers.indexOf(numbers[i]) !== i) {
duplicate = numbers[i];
break; // stop cycle
}
}
console.log(duplicate);
var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
var map = {};
for (var i = 0; i < numbers.length; i++) {
if (map[numbers[i]] !== undefined) {
console.log(map[numbers[i]]);
break;
} else {
map[numbers[i]] = i;
}
}
Okay so let's break this down. What we're doing here is creating a map of numbers to the index at which they first occur. So as we loop through the array of numbers, we check to see if it's in our map of numbers. If it is we've found it and return the value at that key in our map. Otherwise we add the number as a key in our map which points to the index at which it first occurred. The reason we use a map is that it is really fast O(1) so our overall runtime is O(n), which is the fastest you can do this on an unsorted array.
As an alternative, you can use indexOf and lastIndexOf and if values are different, there are multiple repetition and you can break the loop;
function getFirstDuplicate(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i]))
return arr[i];
}
}
var arrWithNumbers = [2, 5, 5, 2, 3, 5, 1, 2, 4];
console.log(getFirstDuplicate(arrWithNumbers))
var numbers = [1, 3, 6, 7, 5, 7, 6, 6, 4, 9, 10, 2, 11]
console.log(getFirstDuplicate(numbers))
I have the same task and came up with this, pretty basic solution:
var arr = [7,4,2,4,5,1,6,8,9,4];
var firstIndex = 0;
for(var i = 0; i < arr.length; i++){
for( var j = i+1; j < arr.length; j++){
if(arr[i] == arr[j]){
firstIndex = arr[i];
break;
}
}
}
console.log(firstIndex);
First for loop takes the first element from array (number 7), then the other for loop checks all other elements against it, and so on.
Important here is to define j in second loop as i+1, if not, any element would find it's equal number at the same index and firstIndex would get the value of the last one after all loops are done.
To reduce the time complexity in the aforementioned answers you can go with this solution:
function getFirstRecurringNumber(arrayOfNumbers) {
const hashMap = new Map();
for (let number of arrayOfNumbers) { // Time complexity: O(n)
const numberDuplicatesCount = hashMap.get(number);
if (numberDuplicatesCount) {
hashMap.set(number, numberDuplicatesCount + 1);
continue;
}
hashMap.set(number, 1); // Space complexity: O(n)
}
for (let entry of hashMap.entries()) { // Time complexity: O(i)
if (entry[1] > 1) {
return entry[0];
}
}
}
// Time complexity: O(n + i) instead of O(n^2)
// Space complexity: O(n)
Using the code below, I am able to get just the first '5' that appears in the array. the .some() method stops looping through once it finds a match.
let james = [5, 1, 5, 8, 2, 7, 5, 8, 3, 5];
let onlyOneFives = [];
james.some(item => {
//checking for a condition.
if(james.indexOf(item) === 0) {
//if the condition is met, then it pushes the item to a new array and then
//returns true which stop the loop
onlyOneFives.push(item);
return james.indexOf(item) === 0;
}
})
console.log(onlyOneFives)
Create a function that takes an array with numbers, inside it do the following:
First, instantiate an empty object.
Secondly, make a for loop that iterates trough every element of the array and for each one, add them to the empty object and check if the length of the object has changed, if not, well that means that you added a element that already existed so you can return it:
//Return first recurring number of given array, if there isn't return undefined.
const firstRecurringNumberOf = array =>{
objectOfArray = {};
for (let dynamicIndex = 0; dynamicIndex < array.length; dynamicIndex ++) {
const elementsBeforeAdding = (Object.keys(objectOfArray)).length;0
objectOfArray[array[dynamicIndex]] = array[dynamicIndex]
const elementsAfterAdding = (Object.keys(objectOfArray)).length;
if(elementsBeforeAdding == elementsAfterAdding){ //it means that the element already existed in the object, so it didnt was added & length doesnt change.
return array[dynamicIndex];
}
}
return undefined;
}
console.log(firstRecurringNumberOf([1,2,3,4])); //returns undefined
console.log(firstRecurringNumberOf([1,4,3,4,2,3])); //returns 4
const arr = [1,9,5,2,3,0,0];
const copiedArray = [...arr];
const index = arr.findIndex((element,i) => {
copiedArray.splice(0,1);
return copiedArray.includes(element)
})
console.log(index);
var addIndex = [7, 5, 2, 3, 4, 5, 7,6, 2];
var firstmatch = [];
for (var i = 0; i < addIndex.length; i++) {
if ($.inArray(addIndex[i], firstmatch) > -1) {
return false;
}
firstmatch.push(addIndex[i]);
}