Incorrect value returns - javascript

I use this function:
function search (){
v = [[2.0], [3.0], [4.0], [5.0]]
if(v.indexOf(2.0) != -1){
Logger.log ('if')
}else{
Logger.log('else')
}
}
editing
My real need is in the values of words like this
I was answered about numbers so I did not change and only added
function search (){
v = [["One"], ["two"], ["three"], ["four"]]
if(v.indexOf("One") != -1){
Logger.log ('if')
}else{
Logger.log('else')
}
}
And instead of "if" returning to me, "else" returns to me.
I apologize for the broken English

You input array is a multi/two dimensional array. You are searching for 2.0 which is actually embedded inside another smaller array. Try changing the function to below.
function search() {
v = [
["One"],
["two"],
["three"],
["four"]
]
if (v.findIndex(e => e[0] === 'One') != -1) {
console.log('if')
} else {
console.log('else')
}
}
search();

You have an array of arrays, so trying to use indexOf on the array of arrays will not work for your case. One option is to use flat and some in conjunction to flatten the array of arrays to one array and then check if the value is found inside the flattened array:
function search (){
v = [[2.0], [3.0], [4.0], [5.0]];
if(v.flat().some((a) => a === 2.0)){
console.log('if');
}else{
console.log('else');
}
}
search();

Did you mean to write
v = [2.0, 3.0, 4.0, 5.0];?
Because that will print out 'if'.
Reason is that in your example, each element of v array is an array of it's own.
If you really want it to be an array of arrays, then to make it work you can do this in the if statement:
if ( v.flat().includes(2.0) )
flat converts it from an array of array that contain a number, to an array of numbers.
includes is a nicer method to check if the array contains a value - no need to check for index :)

array.indexOf() is not applicable for nested array. If your array is primitive types then it's working, but if array is non-primitive types then through indexOf you can't match the value.
Use this instated of your function:
v.findIndex(ele => [...new Set(ele)][0] == 2.0) >=0 ? 'if' : 'else'

Related

Arrays and loops

I need some help with this, I'm stuck in JS Arrays & Loops, I don't know why this is telling me that if the function is empty is not returning "0".
function sumArray (numbers) {
// your code
var numbers = [1, 2, 3, 4];
if (numbers !== undefined) {
const sum = numbers.reduce((a,b) => a+b, 0)
return sum
}
else if ( numbers === []);{
return 0
}
}
sumArray();
I tried to return 0 when the array is empty, but I' don't know what I'm missig.
Beside the missing code, you could just return the result of reduce.
return numbers.reduce((a, b) => a + b, 0);
Some other annotations:
Do not redeclare and assign numbers, because you the the array as parameter.
Do not check against undefined here, because you get always an array as parameter.
You can not check an empty array with comparing another (literally) empty array, because arrays are objects and you compare different object references. For checking if an array is empty, take Array#length property and compare against zero.
The first issue is that you have a line ensuring that numbers is always an array containing 1,2,3,4; so the empty condition will never be met. So that line needs to be removed.
A second issue is that you have an extraneous semicolon that is subtly changing the logic.
The following logic will run the empty statement if numbers references the array object you just created using the array literal synax ([]); then a block will be evaluated outside of the else..if block, returning zero.
else if ( numbers === []);{
return 0
}
If you want to check if an object is an array you can use Array.isArray(foo).
If you want to check if an array is empty, you can test its length (if(myArray.length === 0) ...)
So what you probably meant to write was:
else if (numbers.length === 0) {
return 0
}
...but it turns out that the reduce code will work correctly if the array is of zero length; so that bit of logic is not necessary.
What you want is something like this:
function sumArray(numbers) {
if (!numbers) return 0;
return numbers.reduce((a,b) => a + b, 0);
}
console.log(sumArray())
console.log(sumArray([]))
console.log(sumArray([1, 2, 3, 4]))

Turning a string into an array and saving it as a new array, doesn't return original array

This function cleans up a string (removes all non-alphanumeric characters including underscores) then splits each letter into an array so that it can be reversed, then checked against the original.
At console.log(cleanStr) , it is returning the reversed array but I do not know why.
function checkIfPalindrome(str) {
var cleanStr = str.toLowerCase().replace(replace, "" ).split("");
var reversedStr = cleanStr.reverse();
console.log(cleanStr); // why is this returning reverseStr, the reversed array?
if (cleanStr == reversedStr){
return true
}
return false
}
checkIfPalindrome("five|\_/|four");
The reverse() method reverses an array in place - it mutates the array it's called on. Try creating a new array instead:
const cleanStr = str.toLowerCase().replace(replace, "" ).split("");
const reversedStr = [...cleanStr].reverse();
At console.log(cleanStr) , it is returning the reversed array but I do not know why.
Because reverse reverses it in place.
Separately, you have a problem here:
if (cleanStr == reversedStr){
If they were different arrays, that would always be false, even if they had the same contents.
If you want to make a copy of the array and then reverse it, throw a .slice() in there:
var reversedStr = cleanStr.slice().reverse();
// -----------------------^
...and then compare after turning them back into strings:
if (cleanStr.join("") === reversedStr.join(""))
(I'd probably change those variable names, too, as they don't refer to strings.)
And finally, any time you find yourself writing:
if (x == b) {
return true;
}
return false;
back up and write
return x == b;
instead. :-)

Can I use for loop in _.filter, if not is there any solution in lodash.js?

I am using lodash.js in my project, to get a filtered list from a collection "applicationuser". I am using _.filter method in my js file, initially I am getting an array of records to vm.user=[user1,user2,user3,user4] then I want to get filtered list from applicationuser which contains the userid belongs to vm.userid. Usually when I use _.filter method when I have to compare with only one value like this
vm.userlist= _.filter(applicationuser,function(user){
return user.userid= vm.user.userid
});
But at this situation I have to compare with array of users user id as I mentioned above, I wrote for loop in above code as
vm.userlist= _.filter(applicationuser,function(user){
for( var i=0; i<vm.user.length; i++)
{
return user.userid= vm.user[i].userid
}
});
But I am getting unfiltered list (means all records from applicationuser).
This is the way you can achieve the same with lodash way.
vm.userlist= _.filter(applicationuser,function(user){
return _. some(vm.user, function(vuser){
return vuser.id == user.userid;
});
});
The some function checks whether or not any element exists in the array which matches the predicate. Iteration is stopped once predicate returns truthy.
JSFiddle
You are doing = instead of == (assignment instead of comparison).
vm.userlist = _.filter(applicationuser,function(user){
return user.userid == vm.user.userid
});
lodash filter return true/false if you want the item is on your filtered result. You can rewrite your code as follow:
vm.userlist= _.filter(applicationuser,function(user){
return _.filter(vm.user, function(u) {
return u.userid == user.userid;
}).length>0;
});
I can't speak for lodash, but the algorithm you're proposing has O(n^2) runtime, which isn't good.
You can get O(n) runtime if you store userid values in a hashset (all JavaScript Object instances are hashsets) and use the O(1)-runtime in operator:
var allUserIds = {};
for( var i = 0; i < applicationuser.length; i++ ) {
allUserIds[ applicationuser[i].userid ] = i; // storing the value `i` is arbitrary, you could also just store `null` or `true` some other value.
}
vm.userlist = _.filter( applicationuser, u => u.userid in allUserIds );
You don't need lodash for this really - you can use vanilla JavaScript (ECMAScript 5 or above) using Array.prototype.filter:
vm.userlist = applicationuser.filter( u => u.userid in allUserIds );
Update:
After looking at the lodash documentation, lodash has this functionality built-in as the uniq function, which you can use in one-line, without needing to manually create your own hashmap object:
vm.userlist = _.uniq( applicationuser, u => u.userid );

Removing empty strings from array in javascript

I need help understanding whats going on in my code. I plan on writing a function that takes in a string and removes all letters. The input will be a combination of letters and numbers. I want this function to return an array of all the numbers found in the string. I have successfully written something(with the help of stackoverflow):
number = "32321FDFDS 44"
arr = number.replace(/[A-Za-z]/g," ").split(" ")
for(var i = arr.length - 1; i >= 0; i--){
if(arr[i] == "") {
arr.splice(i, 1);
}
}
This returns
[ '32321', '44' ]
Which is perfect for now. My question is I don't understand how arr.splice(i,1) is removing empty strings. It doesn't make sense that it is removing the empty strings in arr. Can someone help me understand this?
Test :
if (arr[n] == "") // if item `n` within `arr` array `==` `""` , do stuff
See Array.prototype.splice()
With two items within an array :
var arr = ["123", ""];
if (arr[0] == "") {
arr.splice(0,1);
} else {
console.log(arr); // ["123", ""];
};
if (arr[1] == "") {
arr.splice(1,1);
console.log(arr); // ["123"]
};
Unlike other methods that return a new array, leaving the original variable alone, the .splice method mutates an array, making in-place changes to it.
The statement arr.splice(i, 1); means starting at position i remove one item from the array arr. if(arr[i] == "") means if the item at position i is and empty string, do the stuff inside this block. So when the if statement is true that item is removed from the array.
That said unless you need to support ES3 browsers (which effectively means IE8 or below), instead of looping through the array like that, I would just use the .filter method:
var number = "32321FDFDS 44",
arr = number.replace(/[A-Za-z]/g," ").split(" ").filter(function (item) {
return !!item; // all strings except an empty string will coerce to true
});
console.log(arr);
jsFiddle
If you are just trying to extract an array of numeric strings from a string with no other requirements, an even more succinct way of doing it would be to just split on one or more non-numbers:
var number = "32321FDFDS 44",
arr = number.split(/\D+/);
// arr is now [ "32321", "44" ]
console.log(arr);
This does it all in one step without having to filter out empty strings at all.

inArray, indexOf in a 2-dimensional array

i have an 2-dimensional array. for example
var bruecken = [[1,2],[3,4]];
now i am trying to test, if a subarray exists:
console.log(jQuery.inArray([1,2], bruecken));
or
console.log(bruecken.indexOf([1,2]));
but both ways it returns -1. what am i doing wrong?
The fastest way would be to use a for loop and compare them, then return if found. Here is something you can work with, I used JSON for comparison, but you can just use whatever comparator you find best (there are plenty):
function arrayInArray(needle, haystack) {
var i=0, len=haystack.length, target=JSON.stringify(needle);
for(; i<len; i++) {
if (JSON.stringify(haystack[i]) == target) {
return i;
}
}
return -1;
}
arrayInArray( [0,1], [ [1,2], [0,1] ] ); // 1
If you want booleans, just return true instead of i and false instead of -1.
I don't think inArray will work because comparing two identical arrays using == will return false. You could try using grep instead:
function subArrayInArray(subArray, array){
var matches = $.grep(array, function(a){
// Compare the target array with each of the child arrays
return $(subArray).not(a).length == 0 && $(a).not(subArray).length == 0;
});
return !!matches.length;
}
The method for comparing two arrays was stolen from this question

Categories