function ipsBetween(start, end){
var count = 0;
for(var i = 0; i < 4; i++) {
if(start.split('.').slice(i, i + 1) != end.split('.').slice(i, i + 1)) {
count++;
}
}
return count;
}
I am trying to find all possible IP's between a range. The above code is just a starting. I was trying to split the IP in pieces and check if they are equal or not. While I was doing so, interesingly even if the values are equal it evaluates the if statement as true and increases the count. Here is my test case:
ipsBetween("10.0.0.0", "10.0.0.50")
This test case returns 4, whereas it should return 1. I don't know why this is happening. I implicity looked the values of start.split('.').slice(i, i + 1) and end.split('.').slice(i, i + 1) and the first three element is seem to be equal.
There's really no need to use .slice() here. (That's what's causing the problem: .slice() returns an array, and two different arrays will never be equal to each other.) Split the strings first and then just use array indexing:
var count = 0;
start = start.split("."); end = end.split(".");
for (var i = 0; i < start.length; ++i)
if (start[i] != end[i])
count++;
return count;
The reason is that operator != when comparing two list objects will return true if they're not the very same object: split returns a list of strings but slice(i, i+1) will return a list of length 1.
This means that you're comparing ["10"] with another ["10"] and they're two different list objects, so != will return true.
If you just compare the contents using x.slice(".")[i] instead of using slice then the result is what you were expecting.
PS: The operator != of Javascript is terrible and you should not use it and prefer instead !==. It would be the same in this case, but it's much nicer to work with because it doesn't do crazy things when the two types are different.
PS2: Seems a good idea to split the strings at each iteration?
You are comparing arrays not strings you want to compare the string values try this instead:
function ipsBetween(start, end){
var count = 0;
for(var i = 0; i < 4; i++) {
if(start.split('.').slice(i, i + 1)[0] != end.split('.').slice(i, i + 1)[0]) {
count++;
}
}
return count;
}
console.log(ipsBetween("10.0.0.0", "10.0.0.50"));
The problem is the array objects returned won't equal each other because they are not the same array ie. they are not located at the same spot in memory...
Related
I'm basically trying to write a function which when called, performs the action of the endsWith() method
I've tried iterating through the original string and the string to be tested using for loops
function confirmEnding(str, target) {
let strWord = '';
let targetWord = '';
for (let i = (target.length - 1); i >= 0; i--) {
targetWord.concat(target.charAt(i))
for (let j = (str.length - 1); j >= 0; j--) {
strWord.concat(str.charAt(j));
}
}
if (strWord == targetWord) {
return true
} else {
return false
}
}
Now anytime i call the function, it returns true, what's wrong with my code?
concat returns the new string.
Use strWord += whatever; instead.
Primarily, what's wrong with it is that you're using nested loops. There's no need to do that.
The simple, easy way (other than using endsWith!) is to grab the end of str (using the length of target), then compare that substring against target:
function confirmEnding(str, target) {
return str.length >= target.length && str.slice(-target.length) === target;
}
Re your actual code:
concat doesn't modify the string you call it on, it returns a new string (it has to; strings are immutable [unchangeable] in JavaScript)
If you fix #1, your outer loop just copies target to targetWord but in reverse order. Your inner loop copies str to strWord in reverse order repeatedly, so you'll end up with target.length copies of it in strWord.
Nothing in the function tries to take only part of str (the last part, with the same length as target). You end up comparing the full strings (if you fix #1 and #2), not the substring at the end of str.
Finally, just a side note: Any time you find yourself writing:
if (a == b) {
return true;
} else {
return false;
}
you can more concisely and idiomatically write
return a == b;
which does exactly the same thing. :-)
I am working on a practice problem:
Return the length of a string without using javascript's native string.length method.
The only ways I could think of would be substring or slice, but I'm stumped.
You can loop over the string, testing to see whether there is a non-undefined value at each index (as soon as you get an undefined value you've run past the end of the string):
function strLength(s) {
var length = 0;
while (s[length] !== undefined)
length++;
return length;
}
console.log(strLength("Hello")); // 5
console.log(strLength("")); // 0
(I'm assuming that if you're not allowed to use the native string .length property that you probably shouldn't use the array .length property either with str.split("").length...)
Given that this is a practice problem, I suspect the OP may not want ES6/ES2015, but, just in case that's an option, and/or for whoever else is looking at this, here's a concise modern approach:
const str = "Hello world!";
console.log([...str].reduce(a => a+1, 0));
(When I posted this, no other answer had proposed this solution. However, I had missed the fact that #MarkoGrešak had essentially proposed this exact solution in a comment to another question.)
You can use spread element, Array.prototype.keys() iterator, Array.prototype.pop()
var str = "abc";
var len = [...[0,...str].keys()].pop();
console.log(len, str.length);
The briefest have been able to achieve so far using Object.keys(), Array.prototype.pop() and checking for empty string. Approach could probably be improved further.
var len = str === "" ? 0 : +Object.keys(str).pop()+1;
#nnnnnnn utilizes the two methods at above far exceeding the initial attempt in brevity and addressing case of empty string.
var len = +Object.keys(str+' ').pop();
One way would be iterating through a split string like so:
var count = 0;
Array.from("string here".split("")).forEach(function(){count++});
Tip from Marko below in the comments to use the reduce function to shorten it to:
var count = Array.from("string here".split("")).reduce(function(count){return count+1}, 0);
You could use array.length so you answer the question not using the native string.length.
var Str = "Hello world!";
const CountAr = Str.split("").length;
console.log(CountAr);
/*12*/
function stringLength(str) {
var count = 0;
var index = 0;
while(string[index] !== undefined){
count += 1;
index += 1;
}
return count;
}
I think this will work. If you start with '', it won't go into the while loop, and you'll just return 0.
function getStringLength(string) {
var idx = 0;
while (string[idx] !== undefined) {
idx += 1;
}
return idx;
}
This will work.
function length(str) {
str = str.split('');
var length = 0;
str.forEach(function(element) {
length++;
});
return length;
}
length('hello'); // output 5
Yet another way to do it
function getStringLength(str){
var count = 0;
for(var letter in str){
count += 1;
}
return count;
}
console.log(getStringLength('Mississippi')) // 11
console.log(getStringLength('')) // 0
The for in loop is the way to go I think. You can use slice or substring but for in loops can count strings easily too.
function getStringLength(string) {
var length = 0;
for (var i in string){
length++;
}
return length;
}
This is the solution I came up with
I have used a while loop for getting the length of the input
Sharing Two approaches with a while loop
Approach no 1
function getLength(input) {
if(!input){
return 'please provide input'
}
let i = 0;
while (true) {
if (input[i]) {
i += 1
}else{
break
}
}
return i
}
console.log(getLength([1, 5, 3, 7, 8])) // 5
console.log(getLength("Hare Krishna")) // 12
Output
5 (for array)
12 (for string)
Approach no 2
function getLength(input){
let i = 0;
while(input[i] !== undefined){
i++;
}
return i
}
console.log(getLength([1,2,3,48,8,9])) // 6
Output
6 (for array)
function getStringLength(string) {
// Do NOT use any native 'length' methods.
// You might consider using 'substring' or 'slice' as alternatives.
let i = 0;
while (Number(string.slice(i, i+1)) !== 0) {
i++;
} return i;
}
var output = getStringLength('hello');
console.log(output); // --> 5
I want to use JavaScript to determine which class/display color a number of divs(called div1, div2...up through div21) are depending on the values in schedule_array. So if 2 is in schedule_array, I want div2 to be of class clicked and if 3 is not in schedule_array, I want div3 to be of class unclicked. The problem is that my === sign seems to be giving false no matter what for this code:
function setClasses()
{
alert("schedule array is "+schedule_array[3]);
for(var k = 1; k<22; k++)
{
var name = "div" + k;
if(contains(schedule_array, k))
{
document.getElementById(name).className = "clicked";
}
else
{
document.getElementById(name).className = "unclicked";
}
}
}
setClasses();
function contains(a, obj) {
//alert(a[3] + "for function contains");
//alert(a.length);
for (var i = 0; i < a.length; i++) {
document.write(a[i] + "=" + obj);
if (a[i] === obj) {
document.write("true,,,,,,,,");
return true;
}
else
{
document.write("false,,,,,,,,");
}
}
return false;
}
(stole this latter function from http://stackoverflow.com/questions/237104/array-containsobj-in-javascript)
I have no idea why, but the following code's == fails even when I am comparing the same integer to itself. For example with the code below I get output like:
21=21false,,,,,,
As you can see I've already checked to make sure schedule_array exists and has valid numbers. I have also checked to make sure both for loops are running. Finally, I confirmed that in js, even something like "5"==5 should give a true, so even if there is some weird typing going on, that shouldn't affect the outcome.
Question: what is up with this weirdness? What am I doing wrong?
This works for me.
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] == obj) {
return true;
}
}
return false;
}
alert(contains(['1', 2, 3, 4, 5], 1));
Are you sure that a is an array?
http://jsfiddle.net/kjruk00b/
You are using === which is a equality without conversion (strict equality). This means that, that although the numeric value is the same (equality) the strict equality operator is not coercing the String into a Integer to allow this comparison to happen. Switching to the non-strict equality operator == should solve your problem as it will convert the String into an Integer, allowing the comparison to work as you expected.
It may be worth your while looking at the Javascript truth tables for these 2 operators to get an idea for how they work.
This question already has answers here:
JS - jQuery inarray ignoreCase() and contains()
(2 answers)
Closed 9 years ago.
I need to find an object (a string to be precise) inside a large array. While the below code works, it's tediously scrolling through each element of the array, a brute method. Is there a more efficient method? possibly calling on .search or .match or equivalent? Also how to make the search object (string) case insensitive? i.e object might be "abc" while array element is "ABC".
Many thanks in advance
function SearchArray(array, object){ //need to modify code to become case insensitive.
for (var i= 1; i< array.length; i++){
if (array[i] == object.toString()){
return i;
}
}
return 0;
}
I also forgot to mention that the search returns the index / position of the matched object within the one dimensional array, rather than simple true / false.
The following function does just that:
function findWord(array, word) {
return -1 < array.map(function(item) { return item.toLowerCase(); }).indexOf(word.toLowerCase());
}
What it does is:
Converting every string to lower case using the map() function.
Searching for a certain word also in lower case mode.
If the word is found, the function returns a value greater than -1, therefore the return value is either true or false
If you are only going to search the large array once then the only likely optimization is to store the object string representation instead of generating it before each comparison:
function SearchArray(array, object) {
var len=array.length, str=object.toString().toLowerCase();
for (var i=0; i<len; i++) {
if (array[i].toLowerCase() == str) { return i; }
}
return -1; // Return -1 per the "Array.indexOf()" method.
}
However, if you will be searching for many objects within the array then you will save time by storing the lower-case version of the elements:
var lowerArray = array.map(function(x){return x.toString().toLowerCase();});
var lowerObject = object.toString().toLowerCase();
lowerArray.indexOf(lowerObject); // Simply use "Array.indexOf()".
Moreover, if you will be searching this array many times, plenty of memory is available, and performance is critical then you should consider using an object for O(1) lookup:
function makeLowerCaseArrayIndexLookupFunction(array) {
var lookup = array.reduce(function(memo, x, i) {
memo[x.toString().toLowerCase()] = i;
return memo;
}, {});
return function(obj) {
var idx = lookup[obj.toString().toLowerCase()];
return (typeof(idx)==='undefined') ? -1 : idx;
}
}
var findWeekdays = makeLowerCaseArrayIndexLookupFunction([
'Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun'
]);
findWeekdays('mon'); // => 0
findWeekdays('FRI'); // => 4
findWeekdays('x'); // => -1
In Javascript is there a function that returns the number of times that a given string occurs?
I need to return a numeric value that is equal to the number of times that a given string occurs within a particular string for instance:
var myString = "This is a test text"
If I had to search for 'te' in the above string it would return 2.
Very nearly: You can use String#match to do this:
var count = "This is a test text".match(/te/g).length;
That uses the regular expression /te/g (search for "te" literally, globally) and asks the string to return an array of matches. The array's length is then the count.
Naturally that creates an intermediary array, which may not be ideal if you have a large result set. If you don't mind looping:
function countMatches(str, re) {
var counter;
counter = 0;
while (re.test(str)) {
++counter;
}
return counter;
}
var count = countMatches("This is a test text", /te/g);
That uses RegExp#test to find matches without creating intermediary arrays. (Thanks to kennebec for the comment pointing out that my earlier use of RegExp#exec in the above created intermediary arrays unnecessarily!) Whether it's more efficient will depend entirely on how many of these you expect to match, since the version creating the one big array will probably be optimized within the String#match call and so be faster at the expense of more (temporary) memory use — a large result set may bog down trying to allocate memory, but a small one is unlikely to.
Edit Re your comment below, if you're not looking for patterns and you don't mind looping, you may want to do this instead:
function countMatches(str, substr) {
var index, counter, sublength;
sublength = substr.length;
counter = 0;
for (index = str.indexOf(substr);
index >= 0;
index = str.indexOf(substr, index + sublength))
{
++counter;
}
return counter;
}
var count = countMatches("This is a test text", "te");
There's no pre-baked non-RegExp way to do this that I know of.
Here is an implementation of php's substr_count() in js. May this function bring you much joy...
substr_count = function(needle, haystack)
{
var occurrences = 0;
for (var i=0; i < haystack.length; i++)
{
if (needle == haystack.substr(i, needle.length))
{
occurrences++;
}
}
return occurrences;
}
alert(substr_count('hey', 'hey hey ehy w00lzworth'));
I like to use test to count matches- with a global regular expression it works through a string from each lastIndex, like exec, but does not have to build any arrays:
var c=0;
while(rx.test(string)) c++
String.prototype.count= function(rx){
if(typeof rx== 'string') rx= RegExp(rx,'g');
var c= 0;
while(rx.test(this)) c++;
return c;
}