Javascript CharAt method doesnt work for a string - javascript

var teksts= (document.getElementById("teksts").value);
letter=document.getElementById("letter").value;
var results = teksts.split(" ");
document.getElementById("1").innerHTML = results
var count = new Array
for(var i=0; i<results.length; i++)
{
var first= new String (results[i])
for (var j=0; j<first.length; j++)
{if (first.CharAt(j)==letter)
{count [i]++}
}
I have this piece of code in Javascript that is supposed to read a string from HTML and a letter and then find which one of the words has the most of this type of letters in it. So i tried to keep it simple, split the string into an array, have each of the array elements defined as a string and then have a loop go through every letter and if it is the letter that is asked for, mark it in count array.
The problem is, even though i specifically define that the word (in variable first) should be a string and then try to use CharAt method for it to get the specific symbol, i get an error "Uncaught TypeError: Object [object String] has no method 'CharAt' "
I can't with all my googling skills understand why the method won't work for me.

The method name is charAt not CharAt, note the small c
Suggestion 1: var count = new Array should have been var count = []; Its always better to create empty arrays like this, because Array can be anything at runtime as it can be overwritten.
Suggestion 2: It is a good practice to mark the end of lines with ; (semi colon) in javascript.

Related

JavaScript Undefined when alert(array.length) is called [duplicate]

This question already has answers here:
Length of a JavaScript object
(43 answers)
Closed 2 years ago.
Lately I have been trying to create a webpage with a search feature. My way of implementing this, while not the fastest or most elegant, should work in theory. All it does is split the search term into a list, the delimiter being a space, and then splits the keywords (in dictionary format, with the value being a download link, and with the key being the "keywords" I was referring to) and finally, it has an outer loop looping through the keys (being split each iteration into a list), and an inner loop looping through the words input through the input field. If a word in the search field matches one keyword of the key words list, then that key from the dictionary gets a score of +1.
This should sort the keys into order of best result to worst, and then the code can continue on to process all this information and display links to the downloadable files (the point of the webpage is to supply downloads to old software [of which I have collected over the years] etc.). However, when I run the program, whenever the alert(ranking.length) function is called, all I get is undefined in the output window.
Here is the code. (The search() function is called whenever the search button is pressed):
var kw_href = {
"windows":["windows3.1.7z"],
"ms dos 6.22":["ms-dos 6.22.7z"]
}
function search(){
var element = document.getElementById("search_area");
var search_term = element.value.toLowerCase();
var s_tags = search_term.split(" ");
var keys = Object.keys(kw_href);
ranking = {
"windows":0,
"ms dos 6.22":0
};
for (i = 0; i < keys.length; i++){
keywords_arr = keys[i].split(" ");
for (x = 0; x < s_tags.length; x++){
if (keywords_arr.includes(s_tags[x])){
ranking[keys[i]] = ranking[keys[i]] + 1;
}
}
}
// now we have a results list with the best results. Lets sort them into order.
alert(ranking.length);
}
Edit
alert(ranking.length) line is for debugging purposes only, and I was not specifically trying to find the length.
ranking is a generic object, not an array, so it won't have a computed length property.
If you want to count the number of properties in it, convert it to an array with Object.keys(ranking).
ranking should be array of object like ranking =[{"windows":0,"ms dos 6.22":0},{"windows":1,"ms dos 6.22":10}]
Then length ranking.length will work

Uncaught TypeError: undefined is not a function

I'm making a plug-in where I can shorten the title of each entry in a forum index if it is too long. However, that is much harder than I expected.
Everything goes fine except when I get to the part where you actually have to print the items onto the DOM.
I get this error:
Uncaught TypeError: undefined is not a function
Here is my code with a bunch of notes I left to show you how it works.
var minimize = function() {
$('.segment').each(function(){
var title_box = $(this).children('.title');
// Selects the container of the title.
var title = $(this).children('.title').text().trim();
// Takes the child title of the each .segment class and selects its innards.
console.log(title);
var res = title.split("");
// Splits the text into an array.
console.log(res);
var fragment = [];
// initializing the empty array
for (x = 0; x < 4; x++) {
fragment.push(res[x]);
console.log(fragment);
// Loops through to make sure it's not more than 5 characters long
};
var final = fragment.join("");
// Joins the broken up string together.
title_box.empty();
final.appendTo(title_box);
});
};
What do you think I did wrong? And if there's any other ways for me to make this code more efficient, then please don't hesitate to tell me.
Right here you define fragment as an array:
var fragment = [];
You then populate it and do this:
var final = fragment.join("");
Read the docs on array.join to understand what that function does. In short, it joins your array together into a string
So now when you do this:
final.appendTo(title_box);
You get your TypeError because string doesn't have an appendTo method
What you probably wanted was a jquery object to call appendTo on.
Perhaps you meant:
title_box.text(final);

Matching Array to JavaScript Matrix

I’m wondering how to solve a matching/lookup problem and I “think” a multi-dimensional array is the solution. In short, I want to match a list of comma separated SKUs stored as a cookie value against a finite list of SKUs with matching product names and print out the matched product names onto the page. I’m not sure if this is the best way to do this, but with what I have so far I’m not clear how to properly breakup the comma separated strings from the cookie (right now it’s trying to match the entire cookie value), match them to the matrix (17 total rows) and then print out the Product Name.
<script>
var staticList = [
[“1234”, “Chocolate Ice Cream”],
[“1235”, “Peanut Butter Cookie”],
[“6G2Y”, “Raspberry Jell-O”],
[“YY23”, “Vanilla Wafers”]
];
var cookieSkus = [‘1235,YY23’]; // comma separated value from cookie
jQuery(function () {
for (var i = 0; i < staticList.length; i++) {
if (cookieSkus.indexOf(staticList [i][0]) > -1) {
jQuery('#pdisplay).append(staticList [i] [1] + '<br />');
}
}
});
</script>
<p id=”pdisplay”></p>
In this example, the paragraph "pdisplay" would contain:
Peanut Butter Cookie
Vanilla Wafers
Is there a way to correct what I have above or is there a better method of accomplishing what I’m trying to do?
First, you might want to focus on the Cookie SKUs rather than the staticList. The reason for this is that the cookie may have a variable number, and may be as small as 0 elements. (After all, we don't need to list the items if there are no items).
This may be accomplished simply by converting the string to an array and then checking if the SKU is in the staticList. Unfortunately, since you are using a multidimensional array, this would require going through the staticList for each cookie sku. Using just this suggestion, here is a basic example and fiddle:
Rewrite: Accounting for the fact that staticList is an Array of Arrays
jQuery(function() {
var skus = cookieSkus[0].split(',');
for (var i = 0; i < skus.length; i++) {
for (var j = 0; j < staticList.length; j++) {
if (staticList[j][0] == skus[i]) {
jQuery('#pdisplay').append(staticList[j][2] + '<br/>');
break; // Will end inner if the item is found... Saves a lot of extra time.
}
}
}
});
Edit 2: Using an Object (A possibly better approach)
According to the comments, you must support IE8. In this case, you might consider an Object instead of a multi-dimensional array. The reasons for this are as follows:
An object is actually an associative array (with a few perks).
You can directly check for property existence without having any nested arrays.
Object property access is typically faster than looping through an array
You can access object properties nearly exactly like accessing an array's elements.
When using an Object, the original version of my code may be used without modification. This is because the object's structure is simpler. Here is a fiddle for you: option 2
var staticList = {
"1234": "Chocolate Ice Cream",
"1235": "Peanut Butter Cookie",
"6G2Y": "Raspberry Jell-O",
"YY23": "Vanilla Wafers"
};
jQuery(function() {
var skus = cookieSkus[0].split(',');
for (var i = 0; i < skus.length; i++) {
if (staticList[skus[i]])
jQuery('#pdisplay').append(staticList[skus[i]] + '<br/>');
}
});
Responding to your comment:
The reason that the output matches what is desired is because unlike an array which has numerical indices, the object's indices are the actual skus. So, there is no staticList[0] if staticList is an object. Instead (in the context of the staticList object), 1234 = "Chocolate Ice Cream". So, an object definition basically goes as follows:
var objectName = {
index1: value1,
index2: value2,
...,
...
}
The index may be any primitive value (integer or string). The value may be any valid javascript value including a function or an inner object. Now, to get the value at a specific index, you may do either:
objectName.index1 (no quotes)
OR:
objectName["index1"] (quotes needed if the index is a string)
The result of either of those will be:
value1
It's as simple as that.
I would try something like this:
var cookieSkus = cookieSkus[0].split(',');
staticList.filter(function(cell){
return cookieSkus.some(function(val){return cell[0] === val; });
}).map(function(cell){
jQuery('#pdisplay).append(cell[1] + '<br />');
});
Disclaimer: provided based on the sample code provided above along with recent comments

Shuffle a Questions array and an Answers multidimensional array the same

Alright, so the thing is;
Now I made this website for myself to study japanese more easily, by making a list of japanese words and its definition. I put the japanese words in lesson1.txt and the answers in lesson1answers.txt in the same order. I read them out in php and put them in arrays in javascript.
Now the problem is is that these arrays have the same order every time I start the site, which is quite annoying for me as I keep resembling the spot to the answer, and I dont even read the japanese word (Damn our human brains!). So I figured the best way to solve this is by randomizing the elements of both the arrays, but they both have to be randomized in the same pattern because else the question doesnt correspond correctly to the answer anymore.
One of the arrays I have is multidimensional. The array first holds elements that represent the lines I read out of a .txt file. The line has multiple characters in it, consequently the second element of the array represents each character (Dont ask me why I did this, it had to do with me not being able to read out japanese characters in php and put them in js directly). The other array is just the array I keep the answers in.
So I have AnswersArray(); and JapaneseCharactersArray();
I've been stuck on this problem for a whole day now, someone please help or give a hint..
You should merge them into one array of objects:
// assuming AnswersArray.length == JapaneseCharactersArray.length
var array = [];
for (var i=0; i<AnswersArray.length; i++)
array[i] = {
answer: AnswersArray[i],
japanese: JapaneseCharactersArray[i]
};
Now you have only one array, each item containing all information on a single word. You can easily shuffle it now.
Instead of AnswersArray[x] you then would use array[x].answer further down in your code.
Of course, you could just adapt your fisherYates function to shuffle two or more arrays in the same way:
function fisherYates(first/*, ... arrays */) {
var i = first.length,
argl = arguments.length;
if (i == 0) return false;
while (--i) {
var r = Math.floor(Math.random() * (i + 1));
for (var j=0; j<argl; j++) {
var tempi = arguments[j][i];
var tempj = arguments[j][r];
arguments[j][i] = tempj;
arguments[j][r] = tempi;
}
}
}
// usage:
> fisherYates(AnswersArray, JapaneseCharactersArray);
Although the best way is probably to just create them as a single array, another way is to create a new array, of the same length as the others, where each item in the array is a number: 1, 2, 3 ... n. But instead of having the numbers in order, use Math.random() to randomize their order.
Then loop through that new array as such:
for(i=0; i<AnswersArray.length; i++) {
AnswersArray[RandomArray[i]]; // whatever
}
Another way is to just swap the entire row when you randomize the array.

Object has no method 'replace'

I'm try to run this function, which grabs all the checked checkbox values in to a comma separated string, and converts "," in to ", ", so it reads better. The problem is I'm getting a strange error:
$('.name_boxes').live('click', function() {
var all_boxes = $('.name_boxes');
var all_boxes_values = []
for (var i = 0; i < all_boxes.length; i++) {
if (all_boxes[i].checked) {
all_boxes_values.push(all_boxes[i].value)
}
}
var all_boxes_values_clean = all_boxes_values.replace(/,/g,", ");
alert(all_boxes_values_clean);
});
The console error says:
Uncaught TypeError: Object Aaron Ramsey,Aaron Renfree has no method 'replace'.
I'm not getting the alert box.
This is a bit beyond me, can anybody explain what I'm doing wrong?
Although alert(some_array) prints a string representation of the array, the array itself is not a string. Thus, it does not have .replace. alert is forced to convert it into a string because the alert box can only show characters.
You can simply join using a custom separator, though. join is a function of arrays:
var all_boxes_values_clean = all_boxes_values.join(", ");
As a side note, I recommend console.log over alert because it:
shows the actual object/array instead of a string representation (especially useful with objects instead of the useless [object Object] you receive with alert)
frees you from closing the popup each time
keeps track of other logs so that you have an actual log of logs
all_boxes_values is an array, not a strings and thus it has no replace method.
Try
var all_boxes_values_clean = all_boxes_values.join(", ");
If you insist on performing regular expressions, convert an array to string first: all_boxes_values.toString().

Categories