Backwards loop only printing undefined - javascript

I am attempting to create a function that can take in an array and display its contents backwards. I am having trouble with understanding why my function call is showing undefined when I enter an array in its parameter.
var arrayOne = []
function printReverse(arrayOne) {
for(var i = arrayOne.length-1; i < 0; i--) {
console.log(arrayOne[i])
}
}

There is a misunderstading with your question:
What you want to achieve is console.log elements on screen, not return anything.
Your code
var arrayOne = []
function printReverse(arrayOne) {
for(var i = arrayOne.length-1; i < 0; i--) {
console.log(arrayOne[i])
}
}
Does not work because you have a wrong operator in your code at i < 0. This will return false at first iteration, because i will be arrayOne.length, which would be > 0 if there is any element on it.
Change this part to i >= 0 and your code will work and actually print the values on console.
However, if you really want to have a reverted array, then you should simply use Array reverse() instead of writing a function to return it.

so there are some fundamentals that are off there. as stated in another answer i will never be less than 0 because you are defining it as a value greater than 0 in your for loop. Give something like this a try
EDIT: the comments are correct in the sense that the array will be mutated so make a copy of the array first which I've added using the spread operator
Also as far as this returning undefined -- it should return undefined unless you comment out the return statement
const arrayOne = [];
function printReverse(array) {
if (!Array.isArray(array) && array.length === 0 ) {
return 'The array is empty';
}
const arrCopy = [...array];
// technically you could just reverse it
// if you return it you have to assign it to someone on the function call
// return arrCopy.reverse();
// if you want to log the reversed array you could also
// console.log(arrCopy.reverse());
// if you want to reverse it then log each single index
// arrCopy.reverse().forEach(function(item) {
// console.log(item);
// })
}
// if you were to just return the reversed array you would have to assign it to a variable
// this is just an example and wouldnt technically work because arrayOne is empty
// also if you use this YOU HAVE TO RETURN THE ARRAY COPY
// const reversedArray = printReverse(arrayOne);

If you want it to return something, you have to add a return within the function, such that
function printReverse(arrayOne) {
for(var i = arrayOne.length-1; i < 0; i--) {
console.log(arrayOne[i]);
}
return "";
}
However, in your case, this doesn't make a lot of sense. You can only return one thing, be it a String, int, array, object, whatever. But once your program hits one return statement, it will quit the function after returning the value.

Related

Conditional response in a map chained to a filter that may return an empty array

I have filter and map function chained. I need to do something conditional on whether a filter returns an empty array or not. However the map function on the array does not seem to be invoked if the filter returns an empty array.
const letters = ["a", "b", "c"];
const numbers = [1, 2, 3]
function result (arr) {
arr.filter((x) => {return x === "a"}).map((y, i, arr) => {
if(arr.length === 0) {
return //do something
} else {
return //do something else
}})
}
Is this expected or am I doing something wrong?
I was expecting the filter result to be passed to the map function, which can be used as the 3rd argument of the map function: map(item, index, array)
Here's a JSFiddle of the problem
https://jsfiddle.net/sub3z0xh/
You’re right about what’s happening. Array methods run once per element in the source array. If the source array is empty, it doesn’t run.
This isn’t new or working different with array methods vs a basic for loop. Example:
const arr = [];
for (let i = 0; i < arr.length; i++) {
console.log(“this code never runs because there are no elements to loop”);
}
So maybe just store the result of the filter in a variable instead. Get rid of the chained map since it may not run. Check the size/contents of your filtered array, then do stuff with that.

Convert an empty value to 0

Consider this / Please try this yourself in the chrome console.
data = [1,,2,,3]
now i want to replace the empty values with 0
data = [1,0,2,0,3]
I did:
data = data.map(e => {
if (e===undefined)
{
return 0;
}
else
{
return e;
}
});
But it is still returning the empty values as empty. what is right way to do this?
The problem is that map doesn't call the function for the missing elements of the array. From MDN:
callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).
The same is true of forEach.
You need to loop through the array indexes rather than using one of the mapping functions.
for (let i = 0; i < data.length; i++) {
if (!(i in data)) {
data[i] = 0;
}
}
Note that using i in data makes it only skip nonexistent entries. If you have an explicit undefined it will be left, e.g.
[1, , undefined, 3, 4]
will become
[1, 0, undefined, 3, 4]
If you want the explicit undefined to be replaced, you can use i === undefined instead.
Array.from() is handy for this. It will use the length to iterate over the array so it won't skip undefined values like map() does. You can pass the value to its second parameter which is a function and return the value or 0:
let data = [1,,2,,3]
let new_array = Array.from(data, i=> i || 0)
console.log(new_array)
Trying looping over the length of the array and filling the gaps:
for(var i = 0; i < data.length; i++)
{
if(typeof(data[i]) === 'undefined')
{
data[i] = 0;
}
}

splice not removing element from array

I am using splice to remove an element from an array, but it's not working.
as far as I know, the code looks okay , but maybe I am missing/overseeing something.
please take a look. here 'state' is an array containing objects.
let removeFromState = state;
for(var i=0;i<removeFromState.length;i++){
if(removeFromState[i].index===action.index){
removeFromState.splice[i,1];
}
}
return removeFromState;
I cant believe, i was being so silly.
and i had been looking at it for quite a while but didnt see it right in front of me. but I am glad i posted it here, because of the remarks about missing entries because I was increasing 'i' even though I was removing entries.
There are two issues:
A typo, you're using [i,1] (square brackets) where you should be using (i,1) (parentheses). Square brackets are property accessors. (The reason this isn't a syntax error is that JavaScript has a comma operator, and [i,1] evaluates to [1]. The reason it's not a runtime error is that functionname[1] looks up the property "1" on the function — and then disregards any value it finds.)
Your loop will skip entries after the entries it removes, because you both remove the entry and increase i. So when you remove entry #5, entry #6 becomes #5 — but then you move on to i == 6. So you never look at the new entry #5.
To fix #2, either only increase i if you don't remove the entry, or loop backward.
So either:
var i = 0;
while (i < removeFromState.length) {
if(removeFromState[i].index === action.index) {
removeFromState.splice(i, 1);
} else {
++i;
}
}
or
for (var i = removeFromState.length - 1; i >= 0; --i) {
if(removeFromState[i].index === action.index) {
removeFromState.splice(i, 1);
}
}
Or alternately, create a new array containing only the entries you want to keep:
var newArray = removeFromState.filter(function(entry) { return entry.index !== action.index; });
splice is a method, you call it with parentheses, not square brackets. Square brackets are for indexing (JavaScript is just excessively relaxed and silently returns undefined when you "index" the method). Try:
removeFromState.splice(i, 1);
I was stuck on the problem for couple of hours. I did figure out that when you splice an array it does returns the element that was spliced from the original array.
let originalArray = ["Apples","Oranges","Kiwi"];
let newArray = originalArray.splice(0,1);
console.log(newArray);
I was expecting the modified originalArray in the spliced variable but instead it returns the element that was spliced.
The answer was to
console.log(originalArray);
Whatever splice returns, we might not need that, we need to check our originalArray since it's the one that got sliced.
The originalArray consists my expected answer which was ["Oranges","Kiwi"]
Mistake was: you used square brackets instead of parenthesis
function remove(state, action) {
let removeFromState = state;
for (var i = 0; i < removeFromState.length; i++) {
if (removeFromState[i].index === action.index) {
removeFromState.splice(i, 1);
i--; // After deleting, counter reduced
}
}
return removeFromState;
}
console.log(remove([{index: 3}, {index: 3}, {index: 3}], {index: 3}));
The problem is how you are calling splice, it is a function and needs to be called like splice(i, 1)
You could simplify the function as below
let removeFromState = state;
const findEntry = entry => entry.index === action.index;
removeFromState.splice(removeFromState.findIndex(findEntry), 1);
return removeFromState;
removeFromState is instantiated as a let constant and therefore not mutable. It should work if let removeFromState is changed to var removeFromState (.

JavaScript function that takes an array as a parameter

I am trying to create a JavaScript function that takes an array as a parameter and returns the first item in the array. This should work for an array of any size. Here is what I have so far, it appears to work just fine in the console but my instructor says there's a better way to do this:
var array = [];
function numbaOne(array) {
for (var i = 0; i < array.length; i++) {
console.log(array[0])
};
}
Any help would be appreciated. I've read about data structures and arrays but can't figure out how to simplify or make this better.
What you are doing is looping over the array and printing out the first item each time. You just want:
var array = [...];
function numbaOne(array) {
console.log(array[0]); // Print out the first value of the array
return array[0]; // Return the first value of the array
}
There is one edge case here. If the array is empty, then the function will fail because array[0] will be undefined.
So, a more complete version might be:
var array = [...];
function numbaOne(array) {
if(array.length > 0) { // Check if there is anything in the array
console.log(array[0]);
return array[0];
} else { // If there isn't, let's return something "bad"
console.log("The array is empty!");
return undefined;
}
}

Get first element of a sparse JavaScript array

I have an array of objects in javascript. I use jquery.
How do i get the first element in the array? I cant use the array index - as I assign each elements index when I am adding the objects to the array. So the indexes arent 0, 1, 2 etc.
Just need to get the first element of the array?
If you don't use sequentially numbered elements, you'll have to loop through until you hit the first one:
var firstIndex = 0;
while (firstIndex < myarray.length && myarray[firstIndex] === undefined) {
firstIndex++;
}
if (firstIndex < myarray.length) {
var firstElement = myarray[firstIndex];
} else {
// no elements.
}
or some equivalently silly construction. This gets you the first item's index, which you might or might not care about it.
If this is something you need to do often, you should keep a lookaside reference to the current first valid index, so this becomes an O(1) operation instead of O(n) every time. If you're frequently needing to iterate through a truly sparse array, consider another data structure, like keeping an object alongside it that back-maps ordinal results to indexes, or something that fits your data.
The filter method works with sparse arrays.
var first = array.filter(x => true)[0];
Have you considered:
function getFirstIndex(array){
var result;
if(array instanceof Array){
for(var i in array){
result = i;
break;
}
} else {
return null;
}
return result;
}
?
And as a way to get the last element in the array:
function getLastIndex(array){
var result;
if(array instanceof Array){
result = array.push("");
array.pop;
}
} else {
return null;
}
return result;
}
Neither of these uses jquery.
Object.keys(array)[0] returns the index (in String form) of the first element in the sparse array.
var array = [];
array[2] = true;
array[5] = undefined;
var keys = Object.keys(array); // => ["2", "5"]
var first = Number(keys[0]); // => 2
var last = Number(keys[keys.length - 1]); // => 5
I was also facing a similar problem and was surprised that no one has considered the following:
var testArray = [];
testArray [1245]= 31;
testArray[2045] = 45;
for(index in testArray){
console.log(index+','+testArray[index])
}
The above will produce
1245,31
2045,45
If needed you could exist after the first iteration if all that was required but generally we need to know where in the array to begin.
This is a proposal with ES5 method with Array#some.
The code gets the first nonsparse element and the index. The iteration stops immediately with returning true in the callback:
var a = [, , 22, 33],
value,
index;
a.some(function (v, i) {
value = v;
index = i;
return true;
});
console.log(index, value);
If you find yourself needing to do manipulation of arrays a lot, you might be interested in the Underscore library. It provides utility methods for manipulating arrays, for example compact:
var yourArray = [];
yourArray[10] = "foo";
var firstValue = _.compact(yourArray)[0];
However, it does sound like you are doing something strange when you are constructing your array. Perhaps Array.push would help you out?

Categories