Javascript function that finds match in an array - javascript

I'm beginning to learn Javascript, and I want to create a function that can sort through an array and compare two values (probably string values).
For example, if there are 50 different words, but there are two "banana" words, I want to know that. Any help on this would be appreciated. Thanks!

You can use filter to find all items that satisfies a filter function. I believe that by sort, you meant traverse or iterate.
E.g.
var words = ['test', 'banana', 'banana', 'other'];
var bananaCount = words.filter(function (word) {
return word == 'banana';
}).length;
console.log(bananaCount); //2
The function needs to work without explicitly stating the word
'banana'. The function needs to find 'banana' programmatically - Team6Labs
Well, you can just adapt the above exemple:
countOfWord(words, 'banana'); //2
function countOfWord(words, word) {
return words.filter(function (w) {
return w == word;
}).length;
}

Related

JS Variable pulling other variables into it

I know the heading of this questions seems vague - but it's because I simply don't know how to summarize it appropriately.
I'm working on a project where I enter some text, and it's translated into something else.
There's a fiddle here.
If I enter 4, it translates to the word for.
If I enter b4, it should translate to before.
Instead, it translates to bfor, because it's capturing the variable 4 as a separate variable.
I've tried changing the order, but it doesn't work. Is this a regex problem?
My variables are identified in the JS.
var replaceValues = {
'4' : 'for',
'b4' : 'before'
}
$('.bs-text').keyup(function (event) {
newText = event.target.value;
for (var txt in replaceValues) {
var temp = new RegExp(txt, 'gim');
newText = newText.replace(temp, replaceValues[txt]);
}
$('.human-text').text(newText);
});
As I noted in the comments, JS objects does not have defined order of its keys, so it is not a good idea to count on this when you know the dictionary will get much bigger.
More about this in another SO question: Does JavaScript Guarantee Object Property Order?
Instead, use simple array that will have the order you define. Sorting of this dictionary array can be done in JS too, you do not need to handle this by your own.
var replaceValues = [
{key: '4', value: 'for'},
{key: 'b4', value: 'before'},
];
// sort the values so longer keys go first
replaceValues.sort((a, b) => b.key.length - a.key.length);
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
for (var txt in replaceValues) {
var replacement = replaceValues[txt];
var temp = new RegExp(replacement.key, 'gim');
newText = newText.replace(temp, replacement.value);
}
$('.human-text').text(newText);
});
You could also use ES6 Map, it should have order guarantied. But be aware that it is not enough to create Map from Object:
A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration.
It should be noted that a Map which is a map of an object, especially a dictionary of dictionaries, will only map to the object's insertion order—which is random and not ordered.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Objects_and_maps_compared
As mentioned in the comments, you have to look for the longest match first. One option is to generate a single regular expression from the search words, ordered by length, and use a callback to get the correct replacement value.
var replaceValues = {
'4': 'for',
'b4': 'before'
};
// generates something equivalent to `/b4|4/gmi`
var pattern = new RegExp(
Object.keys(replaceValues)
.sort((a, b) => b.length - a.length)
.join('|'),
'gmi'
);
var newText = '4 me b4 me';
console.log(newText.replace(pattern, match => replaceValues[match]));
This works because the regex engine matches alternatives from left to right (i.e. if b4 matches it won't try to match 4). Not sure how this solution scales with more searchwords, but it might actually better because you are only matching the string once instead of n times, i.e. the regex engine doesn't have to traverse the whole string multiple times.
The object property has ":" character within property value
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
if (replaceValues[newText]) {
$('.human-text').text(replaceValues[newText])
};
});
jsfiddle http://jsfiddle.net/je89deam/5/

Finding word in javascript

I have an sorted array e.g
var arr = [ "aasd","march","mazz" ,"xav" ];
And i want to find the first occurance of letter that starts with "m" here it would be 1 . Is thee any way how to do it without looping trought whole array?
You could use a binary search to find any word starting with that letter, then loop backwards until you get the first one.
Is there any way how to do it without looping trought whole array?
Yes, loop until you've found the match.
If you want to avoid a for or while construct, you can use Array's find() method.
For example, arr.find(word => word.startsWith("m")) should return the result you expect (or undefined if there's no such word).
You could use the find() function to search for the first match that meets your constraint.
The startsWith() function could easily handle this :
// Your array
var arr = [ "aasd","march","mazz" ,"xav" ];
// This will find the first match that starts with "m"
arr.find(function(word){ return word.startsWith('m');}); // yields "march"
Or if you needed a bit more extensive pattern matching, you could use a regular expression via the test() function, which can be seen in the following example and handles the same scenario (matching a string that begins with "m") :
// Your array
var arr = [ "aasd","march","mazz" ,"xav" ];
// First match that starts with "m"
var match = arr.find(function(word){ return /^m/i.test(word);}); // yields "march"
Example
var arr = ["aasd", "march", "mazz", "xav"];
var match = arr.find(function(word) { return /^m/i.test(word); });
alert(match);
You dont need to loop through the whole array - only until such time as you find what you're interested in
function findFirstIndex(arr, char){
for(var i=0;i<arr.length;i++){
if(arr[i].substring(0,1) === char)
return i;
}
return -1; // not found
}
You could use Array#some()
The some() method tests whether some element in the array passes the test implemented by the provided function.
function find(letter, array) {
var index;
array.some(function (a, i) {
if (a[0] === letter) {
index = i;
return true;
}
});
return index;
}
var arr = ["aasd", "march", "mazz", "xav"];
document.write(find('m', arr));

Partially string search array of javascript objects for a needle

Using the following
haystack = [{'id':'73','name':'Elvis'},{'id':'45','name':'Beatles'}, etc.]
I want to perform a search whereby I can find Elvis by searching for "elv" or "Elv" (thus, a case insensitive search). Results should return in array thus allowing more than one needle to be returned from my search.
My solution is convert my needle into lowercase, no spaces, and use a for loop to go thru my haystack making checks on a lowercase/nospace name. But I suspect there are other more resource friendly methods (I want to know if there is a better way so I can enhance my skillset/knowledge)
I had thought of using jQuery grep or inArray but both appear to be strict with their comparison. And array.filter() was another idea. But various attempts so far fail.
Thanks
Not sure what you tried but .filter() should have worked. Make sure to lowercase both the search string and the name of the searched items.
var searchTerm = 'Elv'.toLowerCase();
var results = haystack.filter(function(item){
return item.name.toLowerCase().indexOf(searchTerm) > -1;
});
alternatively you could use regexp for the comparison
var searchTerm = 'Elv',
search = new RegExp(searchTerm, 'gi');
var results = haystack.filter(function(item){
return item.name.match(search);
});
You can do it with Array#filter and some String's functions
var haystack = [{ 'id': '73', 'name': 'Elvis' }, { 'id': '45', 'name': 'Beatles' }];
var w = 'elv';
function search(word) {
return haystack.filter(function(e) {
return e.name.toLowerCase().substr(0, word.length) == word;
});
}
console.log(search(w));

How can I capture multiple groups, multiple times with javascript regex

I have this code snippet aiming to extract next and last link values from github api...
var types = {},
str = '<https://api.github.com/repositories/1424470/issues?access_token=f554f90b4c95c78091a4202150d4583082dab1ce&page=2>; rel="next", <https://api.github.com/repositories/1424470/issues?access_token=f554f90b4c95c78091a4202150d4583082dab1ce&page=7>; rel="last"',
rex = /\s*<https?:\/\/api.github.com\/.+?&page=(\d+)>;\s*rel="(\w+?)"(?:,|$)/g;
// use regex replace method to capture multiple groups multiple times
str.replace(rex, function(_, page, type){
types[type] = +page;
});
console.log(types);
// {next: 2, last: 7}
It is functioning correctly, but feels like a mis-use of regex replace method, where I am not returning anything, but using it only for the sake of having a callback for each match, which I use to build up an output object.
I would prefer some kind of matchAll, returning multi-dimensional array of matches, and parts.
Is there a better way to handle this case in javascript?
You can use the exec() method in a loop, pushing the match results to a multi-dimensional array.
function find_all(re, s) {
var types = [];
while (m = re.exec(s)) {
types.push([m[2], m[1]])
}
return types;
}
var regex = new RegExp('<https?://[^>]+page=(\\d+)>;\\s*rel="([^"]+)"', 'gi');
find_all(regex, str) //=> [ [ 'next', '2' ], [ 'last', '7' ] ]

Convert variable name to string in Javascript?

I've seen a few other posts about this on Stack Overflow, but the answer always seems to be to create an object with key / value pairs. This doesn't seem to be what I need in my current situation. What I'm wanting to do: I have different arrays which could possibly contain a username. I want to check each array and see if the username is present as a value in them. If it is, I'd like a string representation of a name of the array variable. Example:
var array = ['apple', 'orange', 'grape'];
var array2 = ['apple', 'pear', 'plumb']
member_arrays = new Array();
// I'd like this block to be dynamic in that i don't have to specify the array name
// in the inArray or member_arrays[member_arrays.length+1] (just loop through my arrays
// and add a string representation of the array name to the member_arrays array)
if ($.inArray( 'apple', array ) != -1)
member_arrays[member_arrays.length] = 'array';
if ($.inArray( 'apple', array2) != -1)
member_arrays[member_arrays.length] = 'array2';
// etc...
You cannot do that in JavaScript. That's why people suggest using an object and keeping your "variables" as properties in the object.
By the way, when you're appending to an array, you want just the length, not length + 1:
member_arrays[member_arrays.length] = 'array';
Arrays are zero-based, so the "next" slot is always the "length" value.
edit — well, there is a case where you can do that: when your variables are global. Any global variable named "x" can also be referred to as a property of "window" (for code in a web browser):
var x = 3;
alert(window['x']); // alerts "3"
Please avoid global variables for this purpose :-)
I'm not sure why you'd want to do things this way, but putting that aside, here's an approach that approximates what you seem to be looking for. It does use an object, as others have recommended, but you end up with the "answer array" containing the names of the candidate arrays passing the test.
You do use jQuery in your sample, so I've done so as well. But you can also use the plain JavaScript .indexOf() the same way.
var candidates = {
'array' : ['apple', 'orange', 'grape'],
'array2' : ['apple', 'pear', 'plumb']
};
var member_arrays = [];
for( var test in candidates ){
if( $.inArray( 'apple', candidates[test] ) !== -1 ){ // could use .indexOf()
member_arrays.push( test ); // use push; no need to specify an index
}
}
console.log( member_arrays ); // -> ["array","array2"]

Categories