I am trying to code a program that will remove any zeros, empty strings, null, or undefined values in an array. However when I run this array: [1,null,2,3,0,-1,1.1], through the code below it returns the array with the null and 0 value still in the array. Any help?
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
return arr;
}
}
Because of return arr;, which you have placed inside your for loop. As soon as the code runs through the first element, it hits the return and leaves the function with the array as it was after the first run of the loop.
Just move the return statement outside the for loop, like so:
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
You need to move return arr; outside the for loop.
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
Use .filter() and the falsy value to remove the unwanted items
function cleanArray(arr) {
return arr.filter(function (item) {
return !!item;
//or return arr[i] !== 0 && arr[i] !== '' && arr[i] !== null && arr[i] !== undefined
})
}
very simplistically,
arr = arr.filter(function(item) {
return !!item;
});
but that would let true and other non numeric values through
arr = arr.filter(function(item) {
return !!item && !isNaN(item);
});
may work better (haven't tested it myself - leaves you with something to try)
You can make use of array filter
var arr = [1,null,2,3,0,-1,1.1];
var filteredArr = arr.filter(function(i){
// if in javascript checks for truthy values
if(i) {
return i;
}
});
console.log(filteredArr); // [1, 2, 3, -1, 1.1]
Demo here
function cleanArray(arr) {
var i = 0, newArr = [];
for (i; i < arr.length; i++) {
if (arr[i]) {
newArr.push(arr[i]);
}
}
return newArr;
}
This will work for sure. Hope I was helpful.
Here the fiddle: https://jsfiddle.net/rok_ed/coakcd3L/
Related
This should be something simple, but I miss why this code outputs 'undefined', while I expect to get an array with numbers: [1, 2]. I tried to debug it in console step by step, but still don't understand why newArr doesn't return from the function. Could someone explain, please.
function filterList(arr) {
let newArr = []
for(let i = 0; i <= arr.length; i++) {
if (typeof arr[i] !== "number") {
return
}
if (typeof arr[i] === 'number') {
newArr.push(arr[i])
}
}
return newArr
}
console.log(filterList([1,2,'a','b']))
The first return that is reached inside a function will end the function call and will return whatever you set there.
In your case, you are pushing 2 values in the array, but as soon as you reach the third one a you are just using return. This means that you are returning undefined. You should return newArr
function filterList(arr) {
let newArr = []
for(let i = 0; i <= arr.length; i++) {
if (typeof arr[i] !== "number") {
return newArr
}
if (typeof arr[i] === 'number') {
newArr.push(arr[i])
}
}
return newArr
}
console.log(filterList([1,2,'a','b']))
You're returning from the function immediately on finding an element that isn't a number, and the return value from the function is undefined not the array you've been patiently pushing numbers into. Just remove that statement altogether.
function filterList(arr) {
const newArr = [];
for (let i = 0; i <= arr.length; i++) {
if (typeof arr[i] === 'number') {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(filterList([1, 2, 'a', 'b', 3, 4]))
remove return in for loop
function filterList(arr) {
let newArr = []
for(let i = 0; i < arr.length; i++) {
if (typeof arr[i] === 'number') {
newArr.push(arr[i])
}
}
return newArr
}
const arr = [1,2,'a','b']
console.log(filterList(arr))
// with Array.filter
let result1 = arr.filter(ele => typeof ele === 'number')
console.log(result1)
// with Array.reduce
let result2 = arr.reduce((res, ele) => typeof ele === 'number' ? [...res, ele] : res, [])
console.log(result2)
function stopFunc(isStop = false) {
let total = 0
for(let i = 0; i < 10; i++) {
total += i
if(isStop) return 999
}
return total // return 45
}
console.log(stopFunc())
console.log(stopFunc(true))
you can check stopFunc function in my example, The return statement ends function execution and specifies a value to be returned to the function caller. . in your function :
if (typeof arr[i] !== "number") {
return
}
return omitted, undefined is returned instead.
You can check document return
While taking some online JS tests, I am stuck on why my function for testing if the elements within two arrays are equal is not working. I am using the function to make sure that the new array does not have duplicate values.
The following is my function for testing if the elements of the arrays are equal or not:
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
I call to the function within a for loop, then I test for undefined, because the first time around, the outputArr is empty
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (isEqualArr(tempArr, [outputArr[x]])) {
However, the result shows that there are duplicates:
0: Array [ -1, 0, 1 ]
1: Array [ -1, 2, -1 ]
2: Array []
3: Array [ -1, -1, 2 ]
4: Array []
5: Array [ 0, 1, -1 ]
6: Array [ 0, -1, 1 ]
7: Array [ 1, 0, -1 ]
8: Array [ -1, 0, 1 ]
The other issue is that not only do I have two null arrays (duplicates), but when I test for null before the push, it is not working either:
if(tempArr != null ) {
outputArr.push(tempArr);
}
I have tried tempArr[0] != null, tempArr[0] != '' as well as
if (typeof tempArr[0] != 'undefined')
But it still inserts null arrays into the outputArr.
The following is the premise of the test:
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets. Given nums = [-1,0,1,2,-1,-4]
The following code is my solution, but the duplicate entries, as well as the null entries, makes this an incorrect solution. If you guys can see why my isEqualArr function is at fault, then I would appreciate it.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if (numsLength > 3) {
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
EDIT: I was able to eliminate the null entries by moving the code that checks if it is the first time to run above the for loop:
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
BTW, another thing that is not working if the following logic:
i != j &&
i != k &&
j != k &&
You can see by the outputArr that this logic is being completely ignored.
REFACTORED: even though the online test marked my solution as wrong, you can see with the results, that it is correct. Especially when you factor in the conditionals for making sure that nums[i] != nums[j] and so forth:
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
for (let i = 0; i < numsLength; i++) {
for (let j = 0; j < numsLength; j++) {
for (let k = 0; k < numsLength; k++) {
if (
nums[i] != nums[j] &&
nums[i] != nums[k] &&
nums[j] != nums[k] &&
nums[i] + nums[j] + nums[k] == 0
) {
if (typeof outputArr[0] != 'undefined') {
/**********
* if it reaches this conditional
* then outputArr has at least one element
***********/
if (typeof outputArr[k] != 'undefined') {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
if (isEqualArr(tempArr, outputArr)) {
// do nothing because there is already an element within the array
} else {
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
} else {
// push triplet elements into temp array for the first iteration only
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
// insert tempArr for the first iteration only
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (elem in b) {
for (let i = 0; i < a.length; i++) {
if (a[i] != elem[i]) {
// do nothing
} else {
return true;
}
}
}
return false;
};
RESULTS:
(3) [Array(3), Array(3), Array(3)]
0: (3) [-1, 0, 1]
1: (3) [1, 0, -1]
2: (3) [-1, 1, 0]
length: 3
Your inner for loop is confusing, if you replace it by a forEach you can see what's going on, you should pass as argument outputArr[x] not [outputArr[x]] and there's more stuff.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if(numsLength < 3) return;
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr.push(nums[i], nums[j], nums[k]); // push three at the same time, it's cleaner and avoid problems
outputArr.forEach((arr, index) => {
if(!isEqualArr(arr, outputArr[index])) outputArr.push(tempArr); // outputs correctly
});
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
console.log(threeSum([-1,0,1,2,-1,-4]));
I am a coding beginner and I was writing the following function that checks if the next string of a given array is one unit longer:
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if (i == arr.length-1) { return true }
if (arr[i].length+1 != arr[i+1].length) { return false }
}
}
desired output:
canBuild(["a", "at", "ate", "late", "plate", "plates"]) ➞ true
canBuild(["it", "bit", "bite", "biters"]) ➞ false
// "biters" is 2 units longer than the previous string
I was wondering if there is a more efficient and shorter way to write the same function, if someone explained me other ways to do so I would really appreciate it!
Use every method and some temp variable (x here)
const canBuild = (arr) => (
(x = arr[0]?.length), arr.every((c) => c.length === x++)
);
console.log(canBuild(["a", "at", "ate", "late", "plate", "plates"]));
console.log(canBuild(["it", "bit", "bite", "biters"]));
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if(i+1 != arr[i].length)
return false;
}
return true;
}
This is a O(n) solution.
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if(i > 0 && arr[i].length !== arr[i-1].length+1)
return false;
}
return true;
}
EDIT: even better, as suggeste by Thomas:
function canBuild(arr) {
for(let i = 1; i < arr.length; i++) {
if(arr[i].length !== arr[i-1].length+1)
return false;
}
return true;
}
I am working on a problem in leetcode. the code is written in javascript.
https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/
Whenever I test the code it returns undefined, however when i put console.log(true) right before my return statement, it prints true, but still does not return true.
var findTarget = function (root, k) {
var stack = [];
var currentNode = root;
var arrayofVals = [];
var traverse = function (currentNode) {
console.log(currentNode);
console.log(stack);
arrayofVals.push(currentNode.val);
if (currentNode.right !== null) {
stack.push(currentNode.right);
}
if (currentNode.left !== null) {
currentNode = currentNode.left;
traverse(currentNode);
}
if (stack.length > 0 ) {
currentNode = stack.pop();
traverse(currentNode);
} else {
console.log(arrayofVals)
for (var i = 0; i <= arrayofVals.length; i++) {
for (var j = 0; j <= arrayofVals.length; j++) {
if (i === j) {
continue;
}
if(arrayofVals[i] + arrayofVals[j] === k) {
console.log(1 === 1);
return (1 === 1);
}
}
}
return false;
}
}
traverse(currentNode);
}
Can someone help me understand why my code returns undefined? I have had this problem before, but only when returning bool.
Thanks for your help!
Right now, findTarget isn't returning anything. You'll want to do return traverse(currentNode);.
I need to search for the presence of an array inside an array. It is similar to jQuery.inArray function.
For
var a = [ [1,2], [1,3] ];
console.log( jQuery.inArray([1,3],a ) )
I get -1 as ans. How to do this?
Thank you
In V8 (that is, Chrome), there is a nifty trick: while == does not work for arrays, <= && >= does.
You can iterate and check for each item if it's appearent:
for(var i = 0; i < a.length; i++) {
if(a[i] >= [1, 3] && a[i] <= [1, 3]) alert(i);
}
For other browsers, you'd need a function that checks for array equality:
http://www.svendtofte.com/code/usefull_prototypes/prototypes.js
Array.prototype.compareArrays = function(arr) {
if (this.length != arr.length) return false;
for (var i = 0; i < arr.length; i++) {
if (this[i].compareArrays) { //likely nested array
if (!this[i].compareArrays(arr[i])) return false;
else continue;
}
if (this[i] != arr[i]) return false;
}
return true;
}
Then:
for(var i = 0; i < a.length; i++) {
if(a[i].compareArrays([1, 3])) alert(i);
}
function inArray (needle, haystack) {
for (var idx in haystack) {
if (haystack[idx].join(',') == needle.join(','))
return idx;
}
return -1;
}
try this
function look4arr(arr, v) {
for (var i = 0, l = arr.length; i < l; i += 1) {
if (arr[i].toString() === v.toString()) { //or use +''
return true;
}
}
return false;
}
var a = [[1,2], 2],
ok = [1,2],
ko = [2,3]
look4arr(a, ok); // true
look4arr(a, ko); // false
// as far as the array you are looking at contains primitives seem to work fine
if you need to search for something "more" ...I mean object literals, regexp, functions
You could use a function similar to the following one
function look4x(arr, v) {
for (var i = 0, isObjOrArray = false, l = arr.length; i < l; i += 1) {
isObjOrArray = {}.toString.call(arr[i]).match(/\[object\s(Array|Object)\]/);
if (
(isObjOrArray && JSON.stringify(arr[i])+'' == JSON.stringify(v)+'' )
||
(!isObjOrArray && arr[i].toString() === v.toString())
) {
return true;//or i if a jQuery.inArray output is needed
}
}
return false; // or -1 ... if ... jQuery.inArray
}
var a = [
[1,[1,[1,[1,2]]]],
2,
true,
'hei',
Infinity,
{"o" : "s", 'd':[1,2,3]},
new RegExp(/\s/),
function(){alert('hei');}
],
ok = [1,[1,[1,[1,2]]]];
alert(
look4x(a, [1,[1,[1,[1,2]]]])
&&
look4x(a, true)
&&
look4x(a, 'hei')
&&
look4x(a, Infinity)
&&
look4x(a, {"o" : "s", 'd':[1,2,3]})
&&
look4x(a, new RegExp(/\s/))
&&
look4x(a, function(){alert('hei');})
); // true, in this case
Please note that I didn`t tested it yet with a complete test; I'll post a test asap
Event if I seem to be late, hope it can help someone.
Bye