Issue trying to find length of sequence in an array - javascript

I'm trying to find the length of the sequence in an array, between the first and the second occurance of a specified number.
For Example: lengthOfSequence([0, -3, 7, 4, 0, 3, 7, 9], 7) would return 5, because there are 5 indices between the first and second occurrence of the number 7.
I feel like the code that I have written should work, but after console logging it looks as if my arr.push() method is only pushing the first index to my indexes array variable, and its pushing it twice. Why would this be happening?
Here is my code for context:
var lengthOfSequence = function (arr, n) {
var indexes = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === n) {
indexes.push(arr.indexOf(arr[i]));
}
}
return arr.indexOf(indexes[1]) - arr.indexOf(indexes[0]);
}
So, for example, if I use my array that I used earlier lengthOfSequence([0, -3, 7, 4, 0, 3, 7, 9], 7), my for loop would find the first occurrence of 7 (index 2) and push it to my index array variable, but it would just do it twice. So my indexes array would just be [2,2]. Why would it not be [2,6]?

indexOf does not do what you think it does. It returns the index of the first item that it finds with the provided value. For both values in the array, it returns that first index.
Since you want the index only and you are already iterating over it with your loop, you can simply use i itself:
indexes.push(i);

You may do it as follows but don't know why it is 5 that you want. I guess it should be 4. OK lets make it 5.
function lengthOfSequence(a,f){
var fi = a.indexOf(f);
return a.slice(fi)
.indexOf(f)+(2*fi+1);
}
var a = [0, -3, 7, 4, 0, 3, 7, 9],
f = 7;
console.log(lengthOfSequence(a,f));

You could use just the index and return the difference between the last element of indices and the first one plus one.
var lengthOfSequence = function(arr, n) {
var indexes = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === n) {
indexes.push(i);
}
}
return indexes[indexes.length - 1] - indexes[0] + 1;
}
console.log(lengthOfSequence([0, -3, 7, 4, 0, 3, 7, 9], 7)); // 5
console.log(lengthOfSequence([0, -3, 7, 4, 0, 3, 7, 9], -3)); // 1

Related

Does anyone know why my for loop is stopping at 10 and not completing the rest of index in my array test?

Im trying to take an array of numbers and finding the two adjacent numbers with the highest product. So created a function that multiplies the first two indexes od the array and pushes that product to a new array. My code works for the first index positions but stops and doesn't complete the remaining indexes. What am I doing wrong. This is a code signal practice exercise.
Test: inputArray: [3, 6, -2, -5, 7, 3]
Output: [18, -12, 10]
function solution(inputArray) {
var newArray = []
for (var i = 0; i < inputArray.length; i++) {
const indexOneAndTwoProduct = inputArray[0] * inputArray[1]
newArray.push(indexOneAndTwoProduct)
inputArray.shift()
}
return newArray
}
console.log(solution([3, 6, -2, -5, 7, 3]));
It's a good practice do not modify the same array that you are iterating.
I think that something like this could work:
function solution(inputArray) {
const newArray = []
for (let i = 0; i < inputArray.length - 1; i++) {
const indexOneAndTwoProduct = inputArray[i] * inputArray[i + 1]
newArray.push(indexOneAndTwoProduct)
}
return newArray
}
console.log(solution([3, 6, -2, -5, 7, 3]))

How can you use .indexOf to locate the index of an array where the numbers stop increasing?

I'm taking in an array and need to return the index value where the numbers start to increase or decrease. The numbers in the array either increase then decrease [1, 3, 6, 4, 3](output = 2) decrease then increase [6, 4, 10, 12, 19](output = 1) or the same sequence [1, 3, 5, 7, 9](output = -1). For now I'm just focused on returning the index of an array that increase then decrease, then I think I can figure the other conditions out.
function ArrayChallenge(arr){
for(let i = 0; i < arr.length; i++){
if(arr[i]>arr[i+1]){
console.log(arr.indexOf(arr[i]>arr[i+1]))
}
}
}
console.log(ArrayChallenge([1, 2, 4, 5, 7, 3]))
To me the code says, take in the argument for the parameter(arr), then the for loop will go through each index and compare i with i+1, if i is greater than i+1 that means the sequence is decreasing. If that's the case I'd like to console log the index where that's actually happening. For my example code above the output should be 5 because that's the index where the numbers start decreasing, but I'm getting -1 which means the element cannot be found. If someone knows where I'm going wrong and can point me in the right direction that would be great, I'm pretty sure I'm using the .indexOf method incorrectly, but I don't know why.
"arr[i]>arr[i+1]" returns a bool "true". Your array does not contain any bool values so there is no matching index for it.
Therefore it returns -1 because it can not find any matching element.
EDIT:
If you want to print out the "moment" when your values are decreasing you can try something like this:
console.log('Decreasing from index: ' + arr.indexOf(arr[i]) + ' to ' + arr.indexOf(arr[i + 1]))
Use return arr[i] instead of console.log(arr.indexOf(arr[i]>arr[i+1]))
function ArrayChallenge(arr){
for(let i = 0; i < arr.length; i++){
if(arr[i]>arr[i+1]){
return arr[i]
}
}
}
console.log(ArrayChallenge([1, 2, 4, 5, 7, 3]))
output: 7
You can use ES6 Classes concept to achieve the requirement you have.
Working Demo :
// Defining class using es6
class arrayChallenge {
constructor(input_array) {
this.input_array = input_array;
}
getIncreaseThenDecrease() {
for(let i = 0; i < this.input_array.length; i++) {
if(this.input_array[i]>this.input_array[i+1]) {
return this.input_array.indexOf(this.input_array[i])
}
}
}
getdecreaseThenIncrease() {
for(let i = 0; i < this.input_array.length; i++) {
if(this.input_array[i] < this.input_array[i+1]) {
return this.input_array.indexOf(this.input_array[i])
}
}
}
}
// Making object with the help of the constructor
let arrayChallengeObject = new arrayChallenge([1, 2, 4, 5, 7, 3]);
console.log(arrayChallengeObject.getIncreaseThenDecrease());
console.log(arrayChallengeObject.getdecreaseThenIncrease());

JS, doubling the element of an array and check if the next element of the current element that is doubling is equal to the previous element

I need help to solve this exercise:
An array is given and composed of
whole numbers. Write a function which takes it
as a parameter this array and modifies it by doubling the values. If the previous value and
next value of the current value that is doubling are
equal, change the value of the next element to
0. In other words :
doubling the element of an array and check if the next element(not doublet yet) of the current element that is doubling is equal to the previous element and if so change the next element to 0.
The given array is:
[0, 2, 5, 4, 1, 0, 3, 3, 6, 7];
const nums = [0, 2, 5, 4, 10, 3, 3, 6, 7];
const double = function (arr) {
for (let i = 0; i < arr.length; i++) {
arr[i] *= 2;
console.log(arr[i]);
if ((arr[i - 1] = arr[i + 1])) {
arr[i + 1] = 0;
}
}
return arr;
};
console.log(double(nums));
You could store the preceding value and check if it is equal to the actual element, then store zero or the doubled value.
const
double = array => {
let preceding;
for (let i = 0; i < array.length; i++) {
const value = array[i] * 2;
array[i] = preceding === array[i] ? 0 : value;
preceding = value;
}
return array;
};
console.log(...double([0, 2, 5, 4, 1, 0, 3, 3, 6, 7]));

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 ]

Simple CoffeeScript for loop from End to 0

I am using CoffeeScript and I need to go through an Array from the end to the beginning in order to remove elements. It seemed like a trivial task. Here is my original code which works fine if the list length is bigger than 0 but when the list length is 0, the loop runs from -1 to 0 included.
list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
length = list.length
for i in [length-1..0]
if list[i] >= 3 and list[i] <= 5
list.removeAt(i)
I isolated problem for a length 0 Array:
length = 0
for i in [length-1..0]
console.log '::', i
> :: -1
> :: 0
In regular JavaScript, there would be no problem:
length = 0
for (i = length - 1; i >= 0; i--){
console.log('::', i)
}
// no output
I can't find any way to code a for loop in CoffeeScript that will behave like the JavaScript loop above.
I found an alternative solution using a while loop but it's not pretty. I would like avoiding wrapping my for loop inside an if. Any way to do a CoffeeScript loop for that would behave like the simple JavaScript loop above?
Assuming your end goal is to iterate through a list in reverse order (which seems to be the case based on your original code), you can achieve this in CoffeeScript like
list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
for i in list by -1
console.log i;
which compiles into
var i, j, list;
list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
for (j = list.length - 1; j >= 0; j += -1) {
i = list[j];
console.log(i);
}
You can play around with it to check that it also works for empty lists.
If you need the index in the loop body as well, use
for e, i in list by -1
console.log e // array element
console.log i // array index
You said that you need to loop from the end to the beginning so your loop in js would actually be
for (i = length - 1; i >= 0; i--){
console.log('::', i)
}
In CoffeeScript, this could be implemented as follows:
i = length - 1
while i >= 0
console.log '::', i
i--
More CoffeeScript solution:
list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
new_list = (i for i in list when i < 2 or i > 5)
or only print:
console.log i for i in list when i < 2 or i > 5

Categories

Resources