Find Value in Multidimensional Object Javascript - javascript

I'm trying to dynamically find a particular value inside a multi dimensional object.
To create the object, I'm doing this:
var inViewElements = {};
$('.story-section')
.each(
function(index){
var sectionId = 'story-section-' + Math.floor(Math.random() * (1000 - 1 + 1)) + 1;
$(this).attr('id', sectionId);
var inViewHeight = $(this).height(),
inViewPosTop = $('#' + sectionId).offset().top,
inViewPosBottom = ((inViewPosTop + inViewHeight) - (inViewTolerence + inViewHeight));
inViewElements[inViewPosTop] = {
id: sectionId,
height: inViewHeight,
bottom: inViewPosBottom
};
debug('Inview', 'Object', sectionId);
debug('Inview', 'Height', inViewHeight);
debug('Inview', 'Offset Top', inViewPosTop);
debug('Inview', 'Offset Bottom', inViewPosBottom);
}
);
console.log(inViewElements);
And the output looks like:
What I'm trying to do is compare if another variable value, for example:
var currentPos = '3038';
Matches any of the objects keys. E.g. the 3038 or 2038 etc.
I'm struggling to figure this one out!

So you're trying to search for an object that contains a certain value?
There is no way to query an array/object in Javascript. As you're not using incremental indexes, I would suggest using a foreach loop, using a conditional statement to check whether the property you're trying to match is equal to the value you're looking for.
It would be quicker to use a for loop, however that would require incremental indexes.

If you r logging response variable through which ur output came then u can use this function
for(var x in response){
if( x == 3038) {
// do something
}
}
or
for(var x in response){
if(x == currentPos){
//dosomething
}
}
can u give me the proper code of how u put values to console log so i will edit the answer properly accourding to your question

Related

How to treat array result as array Javascript?

i want to for loop my array result as array because i use nested loop.
Here is my code
var isp = ["yahoo", "gmail"];
var yahoo = ["#yahoo.com", "#rocketmail.com", "#ymail.com"];
var gmail = ["#gmail.com"];
for(x=0;x<isp.length;x++){
//Should alert 3 Because var yahoo contains 3 element
//Should alert 1 because var gmail is contain 1 element
alert(isp[x].length);
for(y=0;y<isp[x].length;y++){
//Should alert #yahoo.com, #rocketmail.com and so on
alert(isp[x][y]);
}
}
Here is my JSFiddle https://jsfiddle.net/4v272ghL/1/
Try this:
https://jsfiddle.net/4v272ghL/2/
var isp = ["yahoo", "gmail"];
var providers = {
'yahoo': ["#yahoo.com", "#rocketmail.com", "#ymail.com"],
'gmail': ["#gmail.com"]
};
isp.forEach(function(v, i) {
console.log(v);
providers[v].forEach(function(domain, index) {
console.log(domain);
});
});
You're using a JS object to hold the arrays of domains instead. Using this, you can access each provider's data dynamically.
Maybe you don't need so many arrays? Lets use an object instead.
var isps = {
yahoo: ["#yahoo.com", "#rocketmail.com", "#ymail.com"],
gmail: ["#gmail.com"]
};
for(isp in isps) {
var providers = isps[isp];
document.write(isp + " has " + providers.length + " provider(s):<br/>");
providers.forEach(function(domain) {
document.write(domain + "<br/>");
});
};
This works because instead of looping through an array and trying to access different variables with the same name, you can instead simply loop through the keys of an object (which are the same as that first array) and use it to access the values of that object (which are the same as in the other variables you had before).
Note that I've changed your alerts to things that will be more informative in running the code snippet. Of course, once you've got access to these values isp, providers and domain, you can do whatever you like with them - you don't need to document.write them.
There are a few benefits to this method. For instance, as we're only human, what if this happened:
var isp = ["yahoo"];
var yahooo = ["#yahoo.com"];
There's a dependency on the values in isp and the variable names being exactly the same. A simple error like above ("yahooo" instead of "yahoo") would prevent the code from working, and a one letter bug like that could be quite difficult to find if you don't know what you're looking for.
If you're to come back and add or modify these values often, this could become a concern. With the object pattern, it's cleaner and more self-contained.
One potential concern with this solution, however, is if the order in which these providers are looped through is important (i.e. if you always need "yahoo" to output before "gmail"). Currently JavaScript states the following in regards to objects: "It is an unordered collection of properties". This could be subject to change in ES6 (we're currently on ES5). Read more about this particular issue here:
Does JavaScript Guarantee Object Property Order?
You will need to eval the isp[x] in order to get the array names of the other two. For example:
var isp = ["yahoo", "gmail"];
var yahoo = ["#yahoo.com", "#rocketmail.com", "#ymail.com"];
var gmail = ["#gmail.com"];
for(x=0;x<isp.length;x++){
//Should alert 3 Because var yahoo contains 3 element
//Should alert 1 because var gmail is contain 1 element
alert(isp[x].length);
for(y=0;y<eval(isp[x]).length;y++){
//Should alert #yahoo.com, #rocketmail.com and so on
alert(eval(isp[x])[y]);
}
}
This is clear i guess right ?
:D
var ispAndData = [
["yahoo", ["#yahoo.com", "#rocketmail.com", "#ymail.com"]],
["gmail", ["#gmail.com"]]
];
for (x = 0; x < ispAndData.length; x++) {
//Should alert 3 Because var yahoo contains 3 element
//Should alert 1 because var gmail is contain 1 element
document.write(ispAndData[x][0] + " -> ");
document.write(ispAndData[x][1].length + "</br>");
for (y = 0; y < ispAndData[x][1].length; y++) {
//Should alert #yahoo.com, #rocketmail.com and so on
document.write(ispAndData[x][1][y] + "</br>");
}
document.write("</br>");
}

Detecting if input has been entered before

Lately I've been having trouble checking whether an input (player name) has been input more than once. This is not in-database, but just based on arrays contained within JavaScript. What I've been using after a couple of google searches was the indexOf() function. However this does not seem to work. My code is as follows:
var numberPlayers = 1;
var players = [];
var AddPlayer = function() {
if(!(players.indexOf($(".name")).val() > -1)) {
players.push($(".name").val());
$(".players").append("<p>Player number " + numberPlayers + " is " + $(".name").val() + "</p>");
numberPlayers++;
}
};
What method of detection would you recommend? I've tried looping, but wouldn't work either.
EDIT: Updated code. Still doesn't work!
Try this - note where the ) is placed:
if(!(players.indexOf($(".name").val()) > -1)) {
instead of:
if(!(players.indexOf($(".name")).val() > -1)) {
and actually, for readability this would be better:
var name = $('.name').val();
if ( players.indexOf(name) == -1)) {
In general, try adding console.log and breakpoints to find your bugs...
You can use an object (read Set / Hash) instead of an array; it should be faster anyway.
Note that I'm also using .text() which will escape text.
var numberPlayers = 1;
var players = {};
var AddPlayer = function() {
var newPlayer = $(".name").val();
if(!(newPlayer in players)) {
players[newPlayer] = true;
$(".players").append($("<p>").text("Player number " + numberPlayers + " is " + newPlayer));
numberPlayers++;
}
};
jQuery has a utility function for this:
$.inArray(value, array)
It returns the index of a value in an array. It returns -1 if the array does not contain the value.

Refer to an array using a variable

I am writing a page that collects serial numbers for parts installed in an assembly. I want to validate the user input on the client-side, if I can.
So if I have multiple dense arrarys, how can I refer to them using a varaiable? For instance, say I have three densely packed arrays who's names represent part numbers, and who's values represent serial numbers (that have been consumed in other assemblies).
arr_PN-123-ABC = ('SN0123','SN0124','SN0125')
arr_PN-456-DEF = ('SN00333','SN00334','SN00335')
arr_PN-789-GHI = ('SN-0001','SN-0002','SN-0003','SN-0004')
function fcnValidateSN(_givenPN, _givenSN) {
//make sure the given values are not null or empty...
//derive the array of serial numbers that coorsponds to the given part number...
var vArrName = "arr_" + vGivenPN;
//loop thru the array of serial numbers to determine if the given sn was already used...
for(var x=0; x < vArrName.length(); x++) {
if(vArrName[x]==_givenSN) {
alert("Serial number '" + _givenSN + "' was already used in another assembly.");
theForm.txtPN.focus();
return;
}
} //end 'for' loop
} //end fcnValidateSN()
So the problem is that 'vArrName' is a string with a value of 'arr_' instead of a refernece to an array who's name is 'arr_'.
I tried wrapping it with the eval() function, but eval() treats dashes as minus signs.
One other note: I cannot use jquery for this effort.
Thank you
You cannot generate a reference to a variable declared with var (except see below). You can use dynamic property names to refer to properties of objects, so:
var arrays = {
"arr_PN-123-ABC": ['SN0123','SN0124','SN0125'],
"arr_PN-456-DEF": ['SN00333','SN00334','SN00335'],
// ...
};
Then:
console.log( arrays["arr_PN-" + num + "ABC"][0] ); // SN0123
Note that you cannot use "-" in a variable name, but you can use it in an object property name.
The exception to not being able to access var variables by dynamic name is made for global variables in a browser. Those variables all end up as properties of the window object.
An array in JavaScript is delimitated by [ and ], not ( or ).
A valid JavaScript variable name can't contain '-'
The length property of an array isn't a function
Well, I've done some (actually, a lot of) adjustments in your code, but I think this is what you need:
var serialGroups = {
PN_123_ABC: ['SN0123','SN0124','SN0125'],
PN_456_DEF: ['SN00333','SN00334','SN00335'],
PN_789_GHI: ['SN-0001','SN-0002','SN-0003','SN-0004']
};
function validateSerial(groupName, sn) {
var serials = serialGroups[groupName];
for(var i=0; i < serials.length; i++){
if(serials[i] == sn) {
alert("Serial number '" + sn + "' was already used in another assembly.");
//Do whatever you want here
return;
}
}
}
Use a single object that has the arrays as elements:
var arr_PN = {
'123-ABC': ('SN0123','SN0124','SN0125'),
'456-DEF': ('SN00333','SN00334','SN00335'),
'789-GHI': ('SN-0001','SN-0002','SN-0003','SN-0004')
}
And then reference using:
var vArrName = arr_PN->{vGivenPN};

Using a variable to search an array instead of a static string

Okay, so what I have is basically three dynamic drop down boxes and a 2D array. I have each box adding their values together, and then I want the sum of the values to be searched for through the array to pull out the fifth value on whatever the row the value was on.
var shape = document.getElementById("shape").value;
var dimension_one = document.getElementById("dimension_One").value;
var x = 'x';
var dimension_two = document.getElementById("dimension_Two").value;
var selected_beam = shape + dimension_one + x + dimension_two; // combine all values from text boxes
alert(selected_beam);
for (i = 0; i < array_shapes.length; i++)
{
if (array_shapes[i][2] == selected_beam) {
alert('Area=' + array_shapes[i][5]);
//Area= array_shapes[i][5]);
}
}
I know that selected _beam is giving me the value I want, and I also know that the array loop returns what I want out of the array but only if I replace
if (array_shapes[i][2] == selected_beam)
with
if (array_shapes[i][2] == "value I want to search for")
So what I really need to know is - why will it only accept it as a string and not as my selected_beam variable.
Based on your array values, it looks like you need var x to be uppercase like:
var x = 'X';
If I am reading your array correctly, it also looks like the beam size is in element 0 and 1 of the array not 1 and 2, so you may need to not look for array_shapes[i][2], but rather array_shapes[i][0] or array_shapes[i][1]
The first item in the array is at index value = 0.
You need to do some debugging.
To start off, you need to know why selected_beam !== "your value".
I suggest you use this function to compare the strings:
function compare( s1, s2 ){
alert("s1: " + s1.toString());
alert("s2: " + s2.toString());
if (s1.toString() == s2.toString())
return alert("true");
return alert("false");
}
>>> compare(selected_beam,"your value");
The problem might be as simple as having unnecessary characters in your selected_beam.
So where you have alert(selected_beam), try to compare the strings and see if it returns true or false.
You are concatenating values that you're parsing from a text box. The result will be a string
Try doing:
var selected_beam = parseInt(shape) + parseInt(dimension_one) + parseInt(x) + parseInt(dimension_two);

How do I check if a variable isnt defined, throw an error that shows me which variable?

I am trying to look if a variable is defined / got an actual object in it, and if not, show me which var doesnt have it.
var $a= $('.a'),
$b= $('.b'),
$c= $('.c');
if ( $a, $b, $c ) /* maybe use .length? and if so, can I use it like this
* ($a, $b, $c).length == 0 ? but like, I need to check every variable once alone! when $a is 3 times present, do not stop here, go on the $b and check if that is == 0... */
alert('No' + $showMeWhichVariable + ' found');
I hope you get what I am trying to do.
thanks in advance!
// You can just loop and check :
var elms = ['.a', '.b', '.c'],
errors = '';
for (var i = 0, len = elms.length; i < len; i++) {
if (!$(elms[i]).length) {
errors += '<li>' + elms[i] + 'doesn\'t exist</li>';
}
}
$('ul').append(errors).appendTo('body');
The variables will not be "undefined". When called with a selector the $() function will always return a jQuery object, with a .length property indicating how many elements matched the selector - if none matched .length will be 0.
elclanrs answer shows how to use a loop to test whether any elements match your three selectors, but assuming you already have a variable such as your $a, that was created with $a = $(".a") then you can test whether the jQuery object referenced by that variable is empty as follows:
if ($a.length === 0) {
// no elements matched, so do something
}
Note that you can call jQuery methods on an empty jQuery object without getting an error, so something like:
$a.hide();
Will hide any and all elements that matched the selector used to create $a but if no elements matched (.length===0) nothing happens - there are no ill effects. You don't have to test .length first.
var object ={};
object['$a'] = $('.a');
object['$b'] = $('.b');
object['$c'] = $('.c');
$.each(object, function(key,value){
if(!object[key]) alert("No "+key+" Found");
});

Categories

Resources