I have an array of characters like this:
['a','b','c','d','f']
['O','Q','R','S']
If we see that, there is one letter is missing from each of the arrays. First one has e missing and the second one has P missing. Care to be taken for the case of the character as well. So, if I have a huge Object which has all the letters in order, and check them for the next ones, and compare?
I am totally confused on what approach to follow! This is what I have got till now:
var chars = ("abcdefghijklmnopqrstuvwxyz"+"abcdefghijklmnopqrstuvwxyz".toUpperCase()).split("");
So this gives me with:
["a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
Which is awesome. Now my question is, how do I like check for the missing character in the range? Some kind of forward lookup?
I tried something like this:
Find the indexOf starting value in the source array.
Compare it with each of them.
If the comparison failed, return the one from the original array?
I think that a much better way is to check for each element in your array if the next element is the next char:
function checkMissingChar(ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) == ar[i-1].charCodeAt(0)+1) {
// console.log('all good');
} else {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(checkMissingChar(a));
console.log(checkMissingChar(b));
Not that I start to check the array with the second item because I compare it to the item before (the first in the Array).
Forward Look-Ahead or Negative Look-Ahead: Well, my solution would be some kind of that. So, if you see this, what I would do is, I'll keep track of them using the Character's Code using charCodeAt, instead of the array.
function findMissingLetter(array) {
var ords = array.map(function (v) {
return v.charCodeAt(0);
});
var prevOrd = "p";
for (var i = 0; i < ords.length; i++) {
if (prevOrd == "p") {
prevOrd = ords[i];
continue;
}
if (prevOrd + 1 != ords[i]) {
return String.fromCharCode(ords[i] - 1);
}
prevOrd = ords[i];
}
}
console.log(findMissingLetter(['a','b','c','d','f']));
console.log(findMissingLetter(['O','Q','R','S']));
Since I come from a PHP background, I use some PHP related terms like ordinal, etc. In PHP, you can get the charCode using the ord().
As Dekel's answer is better than mine, I'll try to propose somewhat more better answer:
function findMissingLetter (ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) != ar[i-1].charCodeAt(0)+1) {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(findMissingLetter(a));
console.log(findMissingLetter(b));
Shorter and Sweet.
I have recently started learning coding and am trying to learn how to create functions but I am finding it quite difficult.
How would write a function called countDots(x) that takes a string as an argument and returns the number of dots (.) it contains.E.g. x = "www.google.com" the function will return with 2.
I would do it this way:
function dotCounter(x) {
return x.split('.').length -1;
}
document.write( dotCounter("www.google.com") );
Please try this
function countDots(x){
return((x.match(/\./g) || []).length)
}
As you say you're learning to code at the moment, you don't need speed-optimised code. I'd suggest this - it only use ideas that turn up in almost all programming languages:
function countDots(str) {
var count = 0;
for (var x = 0; x < str.length; x++) {
if str.charAt(x) == '.' {
count++;
}
}
return count;
}
You can worry about speed once you're happy that you've got the basics! Good luck
I am really having trouble getting my head around crossbrowser recursion in the DOM. I want to get only the text content of a node, but not any HTML tags or other information. Through trial and error, I found that the textContent and innerText attributes don't hold across all browsers, so I have to use the data attribute.
Now the function I have so far is this:
getTextContentXBrowser: function(nodeIn) {
// Currently goes down two levels. Need to abstract further to handle arbitrary number of levels
var tempString = '';
for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
if (nodeIn.childNodes[i].firstChild !== null) {
tempString += nodeIn.childNodes[i].firstChild.data;
} else {
if (nodeIn.childNodes[i].data && nodeIn.childNodes[i].data !== '\n') {
tempString += nodeIn.childNodes[i].data;
}
}
}
return tempString;
},
It's written in object notation, but otherwise it's a pretty standard unremarkable function. It goes down two levels, which is almost good enough for what I want to do, but I want to "set it and forget it" if possible.
I've been at it for four hours and I haven't been able to abstract this to an arbitrary number of levels. Is recursion even my best choice here? Am I missing a better option? How would I convert the above function to recurse?
Thanks for any help!
Update: I rewrote it per dsfq's model, but for some reason, it goes one level down and is unable to go back up afterwards. I realized that my problem previously was that I wasn't concatenating in the second if clause, but this seems to have stopped me short of the goal. Here is my updated function:
getTextContentXBrowser: function(nodeIn) {
var tempString = '';
for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
if (nodeIn.childNodes[i].data) {
tempString += nodeIn.childNodes[i].data;
} else if (nodeIn.childNodes[i].firstChild) {
tempString += this.getTextContentXBrowser(nodeIn.childNodes[i]);
}
}
return tempString.replace(/ /g,'').replace(/\n/g,'');
},
Anyone see what I'm missing?
Have you considered doing this with jQuery?
getTextContentXBrowser: function(nodeIn) {
return $(nodeIn).text();
}
As simple as that!
It can be really simple function calling itself to to replace nodes with its contents. For example:
function flatten(node) {
for (var c = node.childNodes, i = c.length; i--;) {
if (c[i].nodeType == 1) {
c[i].parentNode.replaceChild(document.createTextNode(flatten(c[i]).innerHTML), c[i]);
}
}
}
Looks like in your case you getTextContentXBrowser is a method of some object, so you will need to call it from inside itself properly (in my example I just use function).
Demo: http://jsfiddle.net/7tyYA/
Note that this function replaces nodes with a text in place. If you want a function that just returns a text without modifying actual node right away consider this example with another version of the script:
Demo 2: http://jsfiddle.net/7tyYA/1/
Okay so I have a 2D array that I am trying to alter using javascript. This is what I have so far:
for (var i = 0; i <= inputData.length; i++ {
inputData[0,0] = inputData[0,0];
inputData[i,0] = inputData[((i - 1) + 1/12), 0];
I want this to take array [i-1] value and then add 1/12 to it
for (j = 13; inputData.length; j += 13) {
delete inputData[j,0];
delete inputData[j,1];
}
Also, I want to delete the entire 2D array at every 13th increment value.
}
This is what I have so far. I am sure there are probably errors within it. Can you guys help me out here? Any help would be greatly appreciated.
Couple of things - you need to be careful when iterating over an array that you're removing from, your indexes will end up offset with respect to your data as soon as you do a delete. Secondly your syntax for deletion is off.
Normally in these situations I favour creating a new array containing the data I want to keep.
var inputData = [[1,1],[2,2],[3,3],[4,4]];
var b = [];
for (i=0; i < inputData.length; i++) {
if ((i + 1) % 13 != 0) {
var year_with_month = inputData[i][0] + i * 1/12;
var e = [year_with_month, inputData[i][1]]
b.push(e);
}
}
inputData = b;
Also, given a choice I'd use a library like underscore to make it easy to do the looping. I never manually write for loops anymore, took me a couple of attempts to get that one right :)
This is my first week learning Javascript so this is very new to me. How can I call this function and get it to work. Here is my code.
var ninjaTurtles = ["Leonardo", "Donatello", "Michelangelo", "Raphael"];
function longest(strings) {
var longestName = strings[0];
for (i = 1; i < strings.length; i++) {
if (strings[i].length > longestName.length) {
longestName = strings[i];
}
}
return longestName;
}
longest(ninjaTurtles);
Don't really know what the hell I am doing please help.
EDIT: Okay so I got it to work thanks your help, appreciate it! Now, If i wanted to tweak this same code to get the shortest word out of the array, what do I need to change?
You could turn that entire thing into a one-liner that also handles empty arrays and doesn't pollute the global variable scope using reduce
return strings.reduce(function(a, b) { return a.length > b.length ? a : b }, '')
Demo here - http://jsfiddle.net/xS6Mu/2/