I have a list of /24 IP addresses in an array called subRet
subRet's values are like
10.0.0.1
10.0.0.2
10.0.0.50
10.0.0.80
What I want is a list of IP address that are NOT in the array.
What I've tried is this:
var test=['10.0.0.1','10.0.0.103','10.0.0.111','10.0.0.131','10.0.0.198'];
for(i=1;i<=254;i++){
if( ! $.inArray('10.0.0.'+i.toString(), test ) ) {
console.log("adding "+'10.0.0.'+i.toString());
}
}
Console log says
adding 10.0.0.1
What I want is a list if IP's that are not in the list, like 10.0.0.2.
how?
First, you're not declaring the variable i anywhere, which is bad practice as the scope will likely not be what you expect. Secondly, no need for jQuery here, you can use vanilla ES6. Third, no need to call i.toString as you're concatenating it to a string already, which performs implicit casting.
var test=['10.0.0.1','10.0.0.103','10.0.0.111','10.0.0.131','10.0.0.198'];
for(let i = 1; i <= 254; i++){
if(!test.includes('10.0.0.' + i)) {
console.log("adding 10.0.0." + i);
}
}
The issue of your code is in the way you check the result of the method inArray, since inArray method retrieves the index of the tested IP in the array, and when it finds nothing it returns -1. So you need to make sure that the returned index is higher than -1:
if( ! $.inArray('10.0.0.'+i.toString(), test ) > -1)
Read more about inArray
this worked
var test=['10.0.0.1','10.0.0.103','10.0.0.111','10.0.0.131','10.0.0.198'];
for(i=1;i<=254;i++){
if( ! test.includes('10.0.0.'+i.toString()) ) {
console.log("adding "+'10.0.0.'+i.toString());
}
}
Related
It's hard to even describe the question. I can't reproduce a snippet, obviously because it requires using cookies, but I will try to reproduce it with a normal array, and show you how it should work, then I'll show you screenshots of my code, and the outcome it produces when used on real cookies.
function cookiename(name) {
//var test5 = document.cookie.split(";");
var test5 = ["user=Jim Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
var username2 = name;
var output = "";
if(test5[0].indexOf("user") == 0) {
output = test5[0].substring(username2.length, test5[0].length);
} else alert("IT DOES NOT WORK");
alert(output);
}
cookiename("user");
This is pretty much what my code looks like, except that, instead of array, test5 is assigned to document.cookie.split(";"), and it contains two more cookies.
Now, the way it works is, you create a conditional statement with the array value, in this case, test5[0], which contains the value "user=Jim Jordan", and say, if the indexof("user") string is in position 0 inside the test5[0] string, which contains the value user=Jim Jordan, then execute the condition, if not, alert that it doesn't work.
Now, as you saw, it works great in the above example. It works as expected with any of the other array values. test5[1], test5[2] etc. will work the same way, of course in the above example they won't match the condition, but if you change the indexof string, it works.
Now, the issue I have is that, the test5 variable stores the document.cookie.split(";") array, and only the first array value works, while the others don't, even though the condition should be matching. However, the other values do work but only if the indexof string is intentionally wrong, and doesn't exist inside the array value, and the condition is of course -1. If the indexof string actually exists, both 0 and -1 conditions don't match. Very strange.
Here's a screenshot of my code, and subsequent result:
First array value
So, as you can see, the first value works as expected.
But then, when I try with another array value, it doesn't work. The third array value is called username=Sam Jones. This is what happens when I change indexof("user") with indexof("username").
Third array value
As you can see, the prior alert that I inserted displays that test5[2] contains the value of username=Sam Jones, but then when use it as a condition, the indexof("username") does not match it. It should be 0, but it's not. Even when I try -1, instead of 0, which matches strings that do not exist, it still produces the exact same outcome! Why!?
Now, watch what happens when I add a string in indexof that does not exist. Instead of the string username, I will add something random, and use -1 as a condition.
Different indexof string on Third array value
As you see, now the random indexof string matches the -1, because it doesn't exist. But why when the indexof string actually does exist, neither 0 nor -1 match the condition?
Why only the first array value work?
Does anyone have any idea what is happening here?
Your approach is flawed since you are expecting that the cookie will always be in the same order. You are also checking for the start of a string equals. When you have user, it will also match username. You are not accounting for the = and you are not removing the encoding.
So to do it with your approach with indexOf and substring, you would need to loop over and check that it has a match
function getCookie(key) {
// var myCookies = document.cookie.split(/;\s?/g);
var myCookies = ["user=Jim%20Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
for (var i = 0; i < myCookies.length; i++) {
var current = myCookies[i];
if (current.indexOf(key + "=") === 0) {
return decodeURIComponent(current.substr(key.length+1));
}
}
}
console.log('user', getCookie('user'));
console.log('username', getCookie('username'));
console.log('funky', getCookie('funky'));
Most approaches would use a regular expression.
function getCookie(key) {
// var myCookies = document.cookie;
var myCookies = "user=Jim%20Jordan;color=blue;cat=bella;username=NikoaTesla";
var cookieValue = myCookies.match(`(?:(?:^|.*; *)${key} *= *([^;]*).*$)|^.*$`)[1]
return cookieValue ? decodeURIComponent(cookieValue) : null;
}
console.log('user', getCookie('user'));
console.log('username', getCookie('username'));
console.log('funky', getCookie('funky'));
If I have to read multiple values I would map it to an object
function getCookieValues() {
// var myCookies = document.cookie.split(/;\s?/g);
var myCookies = ["user=Jim%20Jordan", "color=blue", "cat=bella", "username=NikoaTesla"];
return myCookies.reduce(function (obj, item) {
var parts = item.split("=");
obj[parts[0]] = decodeURIComponent(parts[1]);
return obj;
}, {});
}
var myCookies = getCookieValues();
console.log('user', myCookies['user']);
console.log('username', myCookies['username']);
console.log('funky', myCookies['funky']);
What you want is to find cookies starting with name, correct?
Firstly, you are probably aware, but it is good to note that if your cookies come this way: cookies = "user=Jim Jordan; color=blue; cat=bella; username=NikoaTesla";, you have to split for "; " instead of just ";".
Once your splits are correct, already without any leading spaces, you only need:
test5.filter(c=>c.trim().startsWith("user"));
I believe startsWith is cleaner than using indexOf.
Another solution, without split:
For the "; " case:
const cookiestr='; '+cookies+';';
while (true) { i=cookiestr.indexOf('; user',i+1); if (i<0) break; console.log(cookiestr.substring(i+2,cookiestr.indexOf(';',i+1))); }
For the ";" case:
const cookiestr=';'+cookies+';';
while (true) { i=cookiestr.indexOf(';user',i+1); if (i<0) break; console.log(cookiestr.substring(i+1,cookiestr.indexOf(';',i+1))); }
In your conditional, test5[2] = “cat=bella”, not “username=NikolaTesla”. That’s at index 3. Could try that?
Also check for white spaces being being added to the front of end of each string like someone mentioned already.
function addNumifnotThere(numer){
var numCent = [];
numCent.forEach(function(){
if(numer in numCent)
console.log("you logged that");
else
numCent.push(numer);
});
return numCent;
}
This is my current code, what its attempting to do is read an array and if there is already an element exits the loop and says "you already logged that", obviously if it cannot find a similar element then it pushes it to the array.
I want this to work dynamically so we cannot know the size of the array beforehand, so the first element passed as an argument should be put into the array, (addNum(1) should have the array print out [1], calling addNum(1) again should print "you already logged that")
However there are two problems with this
1) Trying to push to a new array without any entries means everything is undefined and therefore trying to traverse the array just causes the program to print [].
2) Adding some random elements to the array just to make it work, in this case numCent=[1,2,3] has other issues, mainly that adding a number above 3 causes the code to print incorrect information. In this case addNum(5) should print [1,2,3,5] but instead prints [1,2,3,5,5,5]
I know this has to be a simple mistake but I've been dragging myself too long to not ask for help.
EDIT: Thanks to the many outstanding answers here I have now leanred about the indexOf method, thank you guys so much.
For every non-match you are pushing the number. Use something like this
var numCent = [];
function addNumifnotThere(numer)
{
var index = numCent.indexOf(number);
if(index >=0)
{
console.log("you logged that");
}
else
{
numCent.push(number);
}
return numCent;
}
Use Array.prototype.indexOf
var numCent = [];
function addNum(numer){
if (numCent.indexOf(numer) > -1)
{
console.log("Number already in array");
}
else
{
numCent.push(numer);
}
}
//DEMO CODE, not part of solution
document.querySelector("button").addEventListener("click", function(){
if (document.querySelector("input").value.length > 0)
{
addNum(document.querySelector("input").value);
document.querySelector("div").innerHTML = numCent.join(", ");
}
}, false);
Output
<div id="output"></div>
<input />
<button>Add number</button>
indexOf tests if an element is inside the array and returns its index. If not found it will return -1. You can test for this. You can try it for your self in this snippet. It will only allow you to add a number (or any string, in this example) once.
I also was confused by the newCent array declaration inside the function. I think, based upon the content of your question, you meant this.
If you want the array held in the instance, you can do it like this.
function AddIf(arr){
if( arr || !this.arr ) {
this.arr = arr || [];
}
return function(number) {
if( this.arr.indexOf(number) >= 0 ) {
console.log("Already Present!");
} else {
this.arr.push(number);
}
return this.arr;
}.bind(this);
}
// Usage would be like this:
// var addIf = new AddIf([1, 2, 3]);
// addIf(10); // returns [1, 2, 3, 10]
// addIf(10); // logs "Already Present!", doesn't add 10 to array
This basically returns a function, with this bound to the function being called. If you pass in an initial array, it will use that array to compare to when adding it to the array.
You can catch the return function and call it as you would want to. If you don't call new when invoking however, it will share the same array instance (and have a funky way of being called, AddIf()(10)).
I used fn.bind() to ensure the function gets called in the correct context every time, if you were wondering why I called it like that.
Do do this cleanly, I'd consider prototyping the global Array object and adding a method to push values but only if they're unique to the array. Something like this:
Array.prototype.pushUnique = function (item) {
if (this.indexOf(item) != -1) {
console.log("Item with value of " + item + " already exists in the array."
}
else {
this.push(item);
}
}
If you're not comfortable prototypeing global types like Array, you can build the same thing in a procedural pattern:
function arrayPushUnique (arr, item) {
if (arr.indexOf(item) != -1) {
console.log("Item with value of " + item + " already exists in the array."
}
else {
arr.push(item);
}
}
Then to use it, simply create a new empty array and start pushing things to it.
var numCent = [];
// The Array.prototype method
numCent.pushUnique(number);
// The procedural method
arrayPushUnique(numCent, number);
I'm pulling my hair out over this one. I have two arrays, likes & dislikes, both filled with about 50 strings each.
I also have a JSON object, data.results, which contains about 50 objects, each with an _id parameter.
I'm trying to check find all the objects within data.results that aren't in both likes and dislikes.
Here's my code at present:
var newResults = []
for(var i = 0; i<data.results.length; i++){
for(var x = 0; x<likes.length; x++){
if(!(data.results[i]._id == likes[x])){
for(var y = 0; y<dislikes.length; y++){
if(!(data.results[i]._id == dislikes[y])){
newResults.push(data.results[i]);
console.log("pushed " + data.results[i]._id);
}
else
{
console.log("They already HATE " + data.results[i]._id + " foo!"); //temp
}
}
}
else
{
console.log(data.results[i]._id + " is already liked!"); //temp
}
}
}
As you can see, I'm iterating through all the data.results objects. Then I check whether their _id is in likes. If it isn't, I check whether it's in dislikes. Then if it still isn't, I push it to newResults.
As you might expect by looking at it, this code currently pushes the result into my array once for each iteration, so i end up with a massive array of like 600 objects.
What's the good, simple way to achieve this?
for (var i = 0; i < data.results.length; i++) {
isInLiked = (likes.indexOf(data.results[i]) > -1);
isInHated = (dislikes.indexOf(data.results[i]) > -1);
if (!isInLiked && !isInHated) {
etc...
}
}
When checking whether an Array contains an element, Array.prototype.indexOf (which is ECMAScript 5, but shimmable for older browsers), comes in handy.
Even more when combined with the bitwise NOT operator ~ and a cast to a Boolean !
Lets take a look how this could work.
Array.prototype.indexOf returns -1 if an Element is not found.
Applying a ~ to -1 gives us 0, applying an ! to a 0 gives us true.
So !~[...].indexOf (var) gives us a Boolean represantation, of whether an Element is NOT in an Array. The other way round !!~[...].indexOf (var) would yield true if an Element was found.
Let's wrap this logic in a contains function, to simply reuse it.
function contains (array,element) {
return !!~array.indexOf (element);
}
Now we only need an logical AND && to combine the output, of your 2 arrays, passed to the contains function.
var likes = ["a","b","f"] //your likes
var dislikes = ["c","g","h"] //your dislikes
var result = ["a","c","d","e","f"]; //the result containing the strings
var newresult = []; //the new result you want the strings which are NOT in likes or dislikes, being pushed to
for (var i = 0,j;j=result[i++];) //iterate over the results array
if (!contains(likes,j) && !contains (dislikes,j)) //check if it is NOT in likes AND NOT in dislikes
newresult.push (j) //if so, push it to the newresult array.
console.log (newresult) // ["d","e"]
Here is a Fiddle
Edit notes:
1. Added an contains function, as #Scott suggested
Use likes.indexOf(data.results[i]._id) and dislikes.indexOf(data.results[i]._id).
if (likes.indexOf(data.results[i]._id) != -1)
{
// they like it :D
}
Try first creating an array of common strings between likes and dislikes
var commonStrAry=[];
for(var i = 0; i<likes.length; i++){
for(var j=0; j<dislikes.length; j++){
if(likes[i] === dislikes[j]){
commonStrAry.push(likes[i] );
}
}
}
then you can use this to check against data.results and just remove the elements that don't match.
if($('#this').val().indexOf('4289')){
Do something
else
Do something.
This works only with that 4289,
When I try to add other numbers to be indexed next to it using 'or', it doesn't work. How should I put other number. E.g
IndexOf('4289||78843')
I want this to check this numbers and if the number in the input field is not one of this, to echo error.
Here's more which happens to die when one revisits the field.
$('#Zip').blur(function(){
if (($(this).val().indexOf('0860') > -1)||($(this).val().indexOf('0850') > -1)){
$('#Status_Zip').html("No way.")
$(this).alterClass('*_*', 'Success')
return false;
}else{$('#Status_Code').hide()
$(this).alterClass('*_*', 'Error')
$(this).css('border-color', '#F00').css('background-color', '#FFC').effect("pulsate",{times:4},2)
return true;
}
})
That's because it would be looking for the string '4289||78843', which doesn't exist in the target I'm assuming. Logical operators can't just be tossed in anywhere, only where there are actual values to logically operate on. Something like this:
if(($('#this').val().indexOf('4289') > -1) ||
($('#this').val().indexOf('78843') > -1))
The return value of the indexOf() function is the numeric index of that value in the target value, or -1 if it's not found. So for each value that you're looking for, you'd want to check if it's index is > -1 (which means it's found in the string). Take that whole condition and || it with another condition, and that's a logical operation.
Edit: Regarding your comment, if you want to abstract this into something a little cleaner and more generic you might extract it into its own function which iterates over a collection of strings and returns true if any of them are in the target string. Maybe something like this:
function isAnyValueIn(target, values) {
for (var i = 0; i < values.length; i++) {
if (target.indexOf(values[i]) > -1) {
return true;
}
}
return false;
}
There may even be a more elegant way to do that with .forEach() on the array, but this at least demonstrates the idea. Then elsewhere in the code you'd build the array of values and call the function:
var values = ['4289', '78843'];
var target = $('#this').val();
if (isAnyValueIn(target, values)) {
// At least one value is in the target string
}
This is probably easy for someone.
I am returning a list of campaignIDs (12,45,66) via JSON to a javascript variable
var campaignList = res.DATA.CAMPAIGNS
Now, given a specified campaignID passed in the URL
var campaignId ='<cfoutput>#url.campaignID#</cfoutput>'
I want to check if the returned list contains this campaignID
Any help much appreciated.
Plenty of ways to do it, but I like nice data structures, so ...
Split the list on comma, then loop over list, looking for value:
function campaignExists(campaignList,campaignId) {
aCampaignList = campaignList.split(',');
for (i=0;i<aCampaignList.length;i++) {
if (aCampaignList[i]==campaignId)
return true;
}
return false;
}
Since Array.indexOf sadly isn't cross browser, you're looking at something like:
// assume there is no match
var match_found = false;
// iterate over the campaign list looking for a match,
// set "match_found" to true if we find one
for (var i = 0; i < campaignList.length; i += 1) {
if (parseInt(campaignList[i]) === parseInt(campaignId)) {
match_found = true;
break;
}
}
If you need to do this repeatedly, wrap it in a function
Here's a bit of a "out of the box" solution. You could create a struct for your property id's that you pass into the json searilizer have the key and the value the same. Then you can test the struct for hasOwnProperty. For example:
var campaignIDs = {12 : 12, 45 : 45, 66 : 66};
campaignIDs.hasOwnProperty("12"); //true
campaignIDs.hasOwnProperty("32"); //false
This way if the list is pretty long you wont have to loop through all of the potential properties to find a match. Here's a fiddle to see it in action:
http://jsfiddle.net/bittersweetryan/NeLfk/
I don't like Billy's answer to this, variables within the function have been declared in the global scope and it is somewhat over complicated. If you have a list of ids as a string in your js just search for the id you have from user input.
var patt = new RegExp("(^|,)" + campaignId + "(,|$)");
var foundCampaign = campaignList.search(patt) != -1;