IndexOf Javascript alternative - javascript

I'm trying to do an indexof function. but we're not allowed to use it, or any build-in function in javascript. so i create my own. I upload it in our tester but there's only one condition that I didn't met. Thanks!
here's my code :
function indexofmyversion(searchChar,index) {
var a="";
for(var i=0; i<=searchChar.length; i++){
if(searchChar[i] == index){
return i;
}
} return -1; }

The test failed due to fact that the searching should start from index 4 , simply add another parameter as required
function indexofmyversion(searchChar,index, fromIndex) {
var a="";
for(var i=fromIndex; i<searchChar.length; i++){
if(searchChar[i] == index){
return i;
}
} return -1; }

Related

Comparing two arrays in a class with a loop

I am trying to compare two arrays without using any built in 'compare' functions. I'm getting stuck on how to format the loop to run ( the i >= my_arr.length part) because I feel like part of my issue might be there. I keep getting true even when the two arrays are different. This is a function I'm writing inside of a class. Thanks in advance
is_equal(other_arr){
let result=[];
for(let i =0; i >= my_arr.length; i++){
if(MySet[i] === other_arr[i]){
return true;
}else{
return false;
}}}}
I'd change it around slightly like this:
is_equal(other_arr){
if (my_arr.length != MySet.length) return false;
for(let i =0; i >= my_arr.length; i++){
if(MySet[i] !== other_arr[i]){
return false;
}
}
return true;
}
The function you have written returns true on the first equal element contained in the Arrays. Try the code below:
is_equal(other_arr){
let result=[];
for(let i = 0; i < my_arr.length; i++){
if(MySet[i] !== other_arr[i]){
return false;
}
}
// If the 'for loop' is over, all elements are equal, only then is true return
return true;
}

Javascript - extract letters from an alphanumerical string via loop

Hello there StackOverflow people,
What I expected:
Removing the numbers of the string "23Ka5X". The loop counts the length and the if statement extracts the letters into an array letterMemory. When no letters are in the string, the message '"oh no numbers!" should be the output.
What I ran into:
I have been working on this for some time now but I can't find my mistake. I don't know if I missed a simple detail or made a big mess.
My feeling and console output:
var letterMemory = [];
function orderMsg(mixedMsg) {
for (var loopString = 0; loopString < mixedMsg.length; loopString++); {
if (isNaN(parseInt(mixedMsg.charAt[loopString]))); {
letterMemory.push(mixedMsg.charAt[loopString]);
return letterMemory;
} if (!isNaN(parseInt(mixedMsg.charAt[loopString]))) {
return "oh no numbers!";
}
}
}
console.log(orderMsg("23Ka5X"));
I feel like the issue is trying to push any letter into the array letterMemory via letterMemory.push(mixedMsg.charAt[loopString])
does not work how I imagine it.
I would be really grateful for your help!
I found a simple solution via .replace() but I really want to make it work with a loop and if statements since loops combined with if statements were my latest freecodecamp lessons and I want to get better at it.
The fixed code
function orderMsg(mixedMsg){
var letterMemory = []
for (var loopString = 0; loopString < mixedMsg.length; loopString++){
if (isNaN(mixedMsg[loopString])){
letterMemory.push(mixedMsg[loopString])
}
}
if (letterMemory.length){
return letterMemory
} else {
return 'oh no numbers!'
}
}
The issue was
The for loop was not executing since you terminated it with ; at the end.
charAt is a function, so you either do string.charAt(index), or you can also simply say string[index].
You are using the return statement within the for loop, so what will happen is even if the for loop ran (without the semi-colon at the end), it would run just once.
One other issue is that the variable letterMemory is declared outside the function so that means if you were to call this function twice, it would use the same letterMemory array.
-end of answer-
Additional read: you can use split, filter and ternary operator to condense the function as follows ..
function orderMsg(mixedMsg){
const letterMemory = mixedMsg.split('').filter(isNaN)
return letterMemory.length ? letterMemory : 'oh no numbers!'
}
This could be helpful,
function orderMsg(mixedMsg) {
for (var loopString = 0; loopString < mixedMsg.length; loopString++) {
if (isNaN(parseInt(mixedMsg.charAt(loopString)))) {
letterMemory.push(mixedMsg.charAt(loopString));
}
}
return letterMemory;
}
var arr = orderMsg("23s5");
if (arr.length == 0) {
console.log("oh no numbers!")
} else {
console.log(arr);
}
Use replace with regex globally, replacing all digits by an empty string:
string.replace(/[0-9]/g, "")
You have terminated for loop in the same line with ;.
charAt() is a method.
Return value after for loop ends.
var letterMemory = [];
function orderMsg(mixedMsg) {
for (var loopString = 0; loopString < mixedMsg.length; loopString++) {
var letter=parseInt(mixedMsg.charAt(loopString));
if(isNaN(letter)){
letterMemory.push(mixedMsg.charAt(loopString));
}
}
if(letterMemory.length>0){
return letterMemory;
}
else{
return "Oh no numbers!";
}
}
console.log(orderMsg("23Ka5X"));
Maybe try using .test to match the letters.
function orderMsg(str){
var result = [];
for(var letter of str){
if(/[a-zA-Z]+/g.test(letter)){
result.push(letter)
}
}
if(result.length === 0){
return 'Oh no numbers'
}
return result
}
For a more thorough explanation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

Javascript array search

Whats the best way to search a javascript array for an entry??
All the items will be strings.
Is it simply by using lastIndexOf? like so:
var list= [];
list.push("one");
list.push("two");
list.push("three");
if(list.lastIndexOf(someString) != -1)
{
alert("This is already present in list");
return;
}
Is it simply by using lastIndexOf?
Yes. However, I'd use even simpler indexOf() if you don't need to explicitly search backwards (which you don't if you test for "does not contain"). Also notice that these methods were standardized in ES5 and need to be shimmed in old browsers that do not support them natively.
For older browser support, you should still use a loop:
function inArray(arrToSearch, value) {
for (var i=0; i < arrToSearch.length; i++) {
if (arrToSearch[i] === value) {
return true;
}
}
return false;
};
You can try the build in array method of javascript find. It's the easiest way for your problem. Here is the code:
var list = [], input = "two";
list.push("one");
list.push("two");
list.push("three");
function match(element){
return element == input;
}
if(list.find(match)){
console.log('Match found');
}
var arr = ["one","two","three"];
Array.prototype.find = function(val){
for(var i = 0; i < this.length; i++) {
if(this[i] === val){
alert("found");
return;
}
}
alert("not found");
}
arr.find("two");
Should work in most older browsers.
https://jsfiddle.net/t73e24cp/

How to find index of object in a JavaScript array with jQuery

I am trying to find the index of an object in an array in jquery.
I cannot use jQuery.inArray because i want to match objects on a certain property.
I am using:
jQuery.inObjectArray = function(arr, func)
{
for(var i=0;i<arr.length;i++)
if(func(arr[i]))
return i;
return -1;
}
and then calling:
jQuery.inObjectArray([{Foo:"Bar"}], function(item){return item.Foo == "Bar"})
Is there a built in way?
Not sure why each() doesn't work for you:
BROKEN -- SEE FIX BELOW
function check(arr, closure)
{
$.each(arr,function(idx, val){
// Note, two options are presented below. You only need one.
// Return idx instead of val (in either case) if you want the index
// instead of the value.
// option 1. Just check it inline.
if (val['Foo'] == 'Bar') return val;
// option 2. Run the closure:
if (closure(val)) return val;
});
return -1;
}
Additional example for Op comments.
Array.prototype.UContains = function(closure)
{
var i, pLen = this.length;
for (i = 0; i < pLen; i++)
{
if (closure(this[i])) { return i; }
}
return -1;
}
// usage:
// var closure = function(itm) { return itm.Foo == 'bar'; };
// var index = [{'Foo':'Bar'}].UContains(closure);
Ok, my first example IS HORKED. Pointed out to me after some 6 months and multiple upvotes. : )
Properly, check() should look like this:
function check(arr, closure)
{
var retVal = false; // Set up return value.
$.each(arr,function(idx, val){
// Note, two options are presented below. You only need one.
// Return idx instead of val (in either case) if you want the index
// instead of the value.
// option 1. Just check it inline.
if (val['Foo'] == 'Bar') retVal = true; // Override parent scoped return value.
// option 2. Run the closure:
if (closure(val)) retVal = true;
});
return retVal;
}
The reason here is pretty simple... the scoping of the return was just wrong.
At least the prototype object version (the one I actually checked) worked.
Thanks Crashalot. My bad.

Getting javascript to search an array within an array

I have the following javascript to loop through an array of records, and alert the number of matches found within the array, for each field:
mymusic=[{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}];
tracksArray=[];
trackTitles=[];
var albumScore=0;
var artistScore=0;
var tracksScore=0;
stringToSearchFor="d";
for(i=0;i<mymusic.length;i++){
if((mymusic[i].title).match(stringToSearchFor))
albumScore+=1;
}
if(albumScore!=0)
alert(albumScore+" match(es) found in Albums");
else
alert("No matches found in Albums");
for(d=0;d<mymusic.length;d++){
if((mymusic[d].artist).match(stringToSearchFor))
artistScore+=1;
}
if(artistScore!=0)
alert(artistScore+" match(es) found in Artists");
else
alert("No matches found in Artists");
for(f=0;f<mymusic.length;f++){
tracksArray[f]=mymusic[f].tracks;
for(g=0;g<tracksArray;g++){
trackTitles[g]=tracksArray[g].tracktitle;
}
for(h=0;h<trackTitles.length;h++){
if(trackTitles(h).match(stringToSearchFor))
{
tracksScore+=1;
}
}
}
if(tracksScore!=0)
alert(tracksScore+" match(es) found in Tracks");
else
alert("No matches found in Tracks");
which works fine for the "title" and "artist" records, but always alerts "No matches found" for the "tracks" record, even when there are matches. I guess the problem is with the nested for-loop through the trackTitles array, but I can't see what I can change to make it work. Any ideas?
Thanks
if(trackTitles(h)
You're calling an Array. Should be square brackets.
You could do with breaking out the array handling stuff into reusable functions to improve readability and reduce the number of these stray variables.
Since there are answers with procedural approaches already, here's one based on functional-like array handling for extra fun(*):
function countItemsContaining(seq, prop, str) {
return seq.map(itemGetter(prop)).filter(function(s) {
return s.indexOf(str)!==-1;
}).length;
}
function itemGetter(prop) {
return function(o) {
return o[prop];
};
}
mymusic= [{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}];
needle= 'd';
var titleScore= countItemsContaining(mymusic, 'title', needle);
var artistScore= countItemsContaining(mymusic, 'artist', needle);
// Calling concat is a JavaScript idiom to combine a load of lists into one
//
var mytracks= [].concat.apply([], mymusic.map(itemGetter('tracks')));
var tracksScore= countItemsContaining(mytracks, 'tracktitle', needle);
array.map and array.filter are standardised in ECMAScript Fifth Edition, but aren't available in IE yet, so for compatibility you can define them like this:
if (!('map' in Array.prototype)) {
Array.prototype.map= function(f, that) {
var a= new Array(this.length);
for (var i= 0; i<this.length; i++) if (i in this)
a[i]= f.call(that, this[i], i, this);
return a;
};
}
if (!('filter' in Array.prototype)) {
Array.prototype.filter= function(f, that) {
var a= [];
for (var i= 0; i<this.length; i++) if (i in this)
if (f.call(that, this[i], i, this))
a.push(this[i]);
return a;
};
}
(*: amount of actual fun contained in answer may be limited)
Take a look at the library called underscore.js. It's made for this kind of stuff. These tasks often come down to a line or two of easy-to-read code.
It uses native methods when available, fills in the missing bits (depending on the browser) and is chainable. It even makes the built-in array methods chainable.
Try this instead:
var tracksScore=0;
stringToSearchFor="d";
for(var f=0;f<mymusic.length;f++){
var tracksArray=mymusic[f].tracks;
for(var g=0;g<tracksArray.length;g++) {
var tracktitle=tracksArray[g].tracktitle;
if(tracktitle.match(stringToSearchFor))
{
tracksScore+=1;
}
}
}
if(tracksScore!=0)
alert(tracksScore+" match(es) found in Tracks");
else
alert("No matches found in Tracks");
You have a number of basic errors which ultimately stem from having too many variables. Here is your code refactored:-
mymusic=[{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}];
var albumScore=0;
var artistScore=0;
var tracksScore=0;
stringToSearchFor="d";
for (var i=0; i < mymusic.length; i++)
{
if( mymusic[i].title.match(stringToSearchFor))
albumScore += 1;
if( mymusic[i].artist.match(stringToSearchFor))
artistScore += 1;
for (var j = 0; j < mymusic[i].tracks.length; j++)
{
if (mymusic[i].tracks[j].tracktitle.match(stringToSearchFor))
tracksScore += 1
}
}
if (albumScore != 0)
alert(albumScore + " match(es) found in Albums");
else
alert("No matches found in Albums");
if (artistScore != 0)
alert(artistScore + " match(es) found in Artists");
else
alert("No matches found in Artists");
if (tracksScore != 0)
alert(tracksScore+" match(es) found in Tracks");
else
alert("No matches found in Tracks");
What AnthonyWJones and bobince said (although I'll need to spend some time reading through bobince's answer).
An alternative solution: The moment I saw the data structure I thought "recursion!" and thought it'd be fun to see if I could come up with a solution that would work with any size data structure of any (unknown) depth level.
I do not code frequently, so the below may be riddled with bad practices, but it works :). Let me know your thoughts.
myMusic=[{title:"a",artist:"b",artwork:"c",year:"d",tracks:[{tracktitle:"d",trackmp3:"e"}]}];
function find_match(dataObj,stringToSearchFor,resultObj){
resultObj = (resultObj)?resultObj:{}; //init resultObj
for (dataKey in dataObj){ //loop through dataObj
if (typeof(dataObj[dataKey]) == "object"){ //if property is array/object, call find_match on property
resultObj = find_match(dataObj[dataKey],stringToSearchFor,resultObj);
}else if (dataObj[dataKey].match(stringToSearchFor)){ //else see if search term matches
resultObj[dataKey] = (resultObj[dataKey] )?resultObj[dataKey] +=1:1; //add result to resultObj, init key if not yet found, use dataObj key as resultObj key
}
}
return resultObj; //return resultObj up the chain
}
results = find_match(myMusic,"d");
alertString = "";
for (resultKey in results){ //loop through results and construct alert msg.
alertString += results[resultKey] + " match(es) found in " + resultKey + "\n";
}
alert(alertString );

Categories