I'm trying to resolve some exercises from hacker rank, and I'm struggling with the array map and filter methods.
This function supposes to search a value from queries array into strings array and when I use the map method it returns an array with undefined values, and when I use the filter method it returns an empty array.
var strings = ['ab','ab','bca','acb']
var queries = ['ab','abc','bc']
function matchingStrings(strings, queries) {
let retArr = []
for(let n = 0; n<queries.length; n++){
var equalelem = strings.filter(function(queries){queries[n] === [...strings]})
retArr.push(equalelem.length);
}
return equalelem
}
console.log(matchingStrings(strings, queries))
Looking only at your syntax, and without analyzing the algorithm, the following things should change:
Your filter function always returns undefined. Any function that doesn't have an explicit return statement returns undefined. Maybe you wanted to use an arrow function expression, which doesn't require a return statement if you omit the curly braces?
var equalelem = strings.filter((queries) => queries[n] === [...strings])
Inside the filter function, you seem to be comparing an element from list queries to a copy of list strings. Comparing an element of a list (in this case, a single string) to a list will never be true in your case.
The variable letArr doesn't seem to serve any purpose.
I have below code to check the string is unique or not.
function unique(str) {
let values = [];
for (let letter of str) {
if (values.indexOf(letter) !== -1) {
return false;
}
values.push(letter);
}
return true;
}
console.log(unique("abbds"));
I don't understand the if condition inside properly. Can anyone make me understand this concept?
Here is what your code is doing.
You have string abbds and an array values. In the first iteration
You check the first character a inside values
values.indexOf("a") which results in -1 because a is not present in values.
In this case, values.indexOf("a") since a is not inside values you push it inside values.
If the values has the character in which case the indexOf will return the index of the first occurrence of the item.
And thus values.indexOf(letter) !== -1 will be `true.
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
From MDN : Array.prototype.indexOf()
I am new to JS and was trying to learn how to properly work with indexOf in JS, that is, if you look at the code below:
var sandwiches = ['turkey', 'ham', 'turkey', 'tuna', 'pb&j', 'ham', 'turkey', 'tuna'];
var deduped = sandwiches.filter(function (sandwich, index) {
return sandwiches.indexOf(sandwich) === index;
});
// Logs ["turkey", "ham", "tuna", "pb&j"]
console.log(deduped);
I am trying to remove duplicates but wanted to ask two questions. Firstly, in here return sandwiches.indexOf(sandwich) === index; why we need to use "== index;". Secondly, since indexOf returns index like 0, 1 or 2 ... then why when we console.log(deduped) we get array of names instead of array of indexes. Hope you got my points
You use a method of Javascript Array that is filter, this method take a function that returns a boolean.
The function filter returns a new Array based on the function passed applied to each entry.
If the function return true, then the entry is included in the new Array, otherwise is discarded.
As the functions check the indexOf an entry to be the current index is true for the first occurrency of the entry.
All the duplications will fail the expression as they are not the first index found by indexOf, so they are discarded.
since the logic is to remove the duplicates from the array,
in your example, you have "turkey" as duplicates.
the "turkey" exists in position 0,2,6
so whenever you call indexOf("turkey") always returns 0 because the indexOf function returns the first occurrence of a substring.
so for the elements in position 2 & 6 the condition fails. then it won't return that element.
That is how the filter works in javascript. it evaluates the condition and returns true or false that indicates whether an element to be included in the new array or not, in your example the condition is return sandwiches.indexOf(sandwich) === index;
Perhaps the basic logic is easier to see at a glance if you use arrow notation:
const deduped = myArray => myArray.filter((x, i) => myArray.indexOf(x) === i);
The key point is that indexOf returns the index of the first occurrence of x. For that occurrence the result of the comparison will be true hence the element will be retained by the filter. For any subsequent occurrence the comparison will be false and the filter will reject it.
Difference between === (identity) and == (equality): if type of compared values are different then === will return false, while == will try to convert values to the same type. So, in cases where you compare some values with known types it is better to use ===. (http://www.c-point.com/javascript_tutorial/jsgrpComparison.htm)
You get as result an array of names instead of array of indexes because Array.filter do not change the values, but only filter them. The filter function in your case is return sandwiches.indexOf(sandwich) === index; which return true or false. If you want get the indexes of your items after deduplication, then use map after filter:
a.filter(...).map(function(item, idx) {return idx;})
#Dikens, indexOf gives the index of the element if found. And if the element is not found then it returns -1.
In your case you are filtering the array and storing the values in the deduped. That's why it is showing an array.
If you console the indexOf in the filter function then it will log the index of the element.
For example :
var deduped = sandwiches.filter(function (sandwich, index) {
console.log(sandwiches.indexOf(sandwich));
return sandwiches.indexOf(sandwich) === index;
});
I have a list of objects which have a last name property and I would like to find the object with the last name which the user types in.
I can do this using the underscore filter function which works fine but the case matters. So for example if the last name is Jacobs in my object array and the user types jacobs, it will not find that object. How can I get make the filer find the object regardless of case?
This is how I currently use filter.
var user = _.filter(arr, function(item) {
return item.lastname.indexOf(typedLastName) > -1;
});
Thanks!
var user = _.filter(arr, function(item) {
return item.lastname.toLowerCase().indexOf(typedLastName.toLowerCase()) > -1;
});
Convert both of them to lowercase or uppercase , and then perform comparison
Suppose I have an array of objects called MyArray and that a certain function returns a reference for a particular element within that array; something like this:
MyArray = [Object1, Object2, ..., Objectn];
function DoWork() {
var TheObject = GetTheObject(SomeParamter);
}
At this point, TheObject points to a certain element in the array. Suppose I want to remove this element from MyArray, is this possible without having to reloop through the array to get the index of the element?
I'm looking for something like splice that would work with the reference to the element rather than the index of the element.
Simply use Array.prototype.indexOf:
let index = MyArray.indexOf(TheObject);
if(index !== -1) {
MyArray.splice(index, 1);
}
Keep in mind that if targeting IE < 9 you will need to introduce a polyfill for indexOf; you can find one in the MDN page.