Arrays in arrays, length always is 0, json not working - javascript

I try to create arrays in arrays and then forward it to JSON.
First problem, when i try to use a lista.length or something, console always return 0. I tried to overpass this problem and create another array, but now I have problem with JSON - always return [] - empty lista array.
var lista = [];
var licz = [];
function ListujBledy(value, where) {
var checked = document.getElementById(value).checked;
var desc;
if (value == "blad-tab") {
desc = "Nieprzeźroczysta lista graczy.";
} else if (value == "blad-tab1") {
desc = "Brak listy graczy na początkowym zrzucie ekranu.";
} else if (value == "blad-tab2") {
desc = "Brak listy graczy na końcowym zrzucie ekranu.";
}
if (checked == true) {
if (lista[where] == undefined) {
var temp = [];
temp[value] = desc;
lista[where] = temp;
licz[where] = 1;
} else if (licz[where] == 1) {
var temp = lista[where];
temp[value] = desc;
lista[where] = temp;
licz[where] = 2;
} else if (licz[where] == 2) {
var temp = lista[where];
temp[value] = desc;
lista[where] = temp;
licz[where] = 3;
}
} else {
if (licz[where] == 1) {
delete lista[where];
licz[where] = 0;
} else if (licz[where] == 2) {
delete lista[where][value];
licz[where] = 1;
} else if (licz[where] == 3) {
delete lista[where][value];
licz[where] = 2;
}
}
console.log(lista.length);
console.log(lista);
console.log(JSON.stringify(lista));
console.log("---------------------------------------------------------");
}
Console log from browser:
I don't have more ideas, I can't use lista[0], lista[1] etc. everything must be functional. Eveyrthing is taken from variables but everywhere I was looking for information about it, everybody using numbers in key or permanent keys.
Editied version of code:
I know that checked could have been better done, so I corrected it here.
https://jsfiddle.net/5vdgLtue/1/
The main problem is that even if I do this https://jsfiddle.net/5vdgLtue/0/ the array returns this element, but the length function says it is 0.

It looks like you might be starting out with javascript. Keep in mind that you haven't actually called the function at any point in your code. Is that the case or are you not sharing the full code you have run?

There is only one condition in which the array 'lista' could gain value: if 'check'== true and 'where' == undefined.
In that scenario, you declare the array 'temp' and declare temp[value]= desc. However, if 'value' contains a value different than "blad-tab", "blad-tab1" or "blad-tab2", 'desc' remains empty therefore temp[value] has a name but no value. You are then assigning a named valueless item to lista[where] which would explain why your console displays content but no length. btw, this would be easier if you named your variable something other than 'value' .
Problem is your selector points to the parent element. In jquery you could do this less code but assuming you're not using jQuery. Try something like:
function getDesc(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
//or use getElementsbyClassName...
var checkboxesChecked = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i]);
}
}
for (var i=0; i<checkboxesChecked.length; i++) {
if (checkboxesChecked[i].value === "blad-tab") {
desc = "Nieprzeźroczysta lista graczy.";
} else if (checkboxesChecked[i].value === "blad-tab1") {
desc = "Brak listy graczy na początkowym zrzucie ekranu.";
} else if (checkboxesChecked[i].value === "blad-tab2") {
desc = "Brak listy graczy na końcowym zrzucie ekranu.";
}
}
return desc;
}

This should answer most of your questions.
In summary:
In javascript there are 2 types of arrays: standard arrays and associative arrays
[ ] - standard array - 0 based integer indexes only
{ } - associative array - javascript objects where keys can be any strings
What you are doing is using array in an associative manner. Basically, you are adding properties to your array objects, unlike a standard array where you would only assign values by zero-indexed numbers like temp[0]='something', lista[1]='some other thing' etc.
If you want the length of the key set of the array, then you can use Object.keys(lista).length. This should solve your problem.

Related

Hackerrank: Frequency Queries Timeout

I know that there are plenty of similar questions on SO on this specific thing, but I have a solution that works for all test cases EXCEPT for one (it gets timed out). Is there anyway I can make my code run faster or more efficiently... or do I need to start all over?
My logic:
I create three arrays.
Whenever there is a new value, I add it to my data array. At the same time, I add a "1" to my frequency array. The positions should be the same.
Whenever it is the same value, I simply increase the frequency value for the corresponding value by 1.
Whenever I need to return a value to say whether or not my array has a value with frequency "_", I just indexOf my frequency and tada if it's there I return 0, else I return 1.
function freqQuery(queries) {
var answer = new Array(),
data = new Array(),
frequency = new Array();
for (var i = 0; i < queries.length; i++){
var test = queries[i][0];
if (test == 1) { // first test
var place = data.indexOf(queries[i][1]);
if (place == -1){
data.push(queries[i][1]);
frequency.push(1);
} else {
frequency[place]++;
}
} else if (test == 2) { // second test
var place = data.indexOf(queries[i][1]);
if ((place != -1) && (frequency[place] > 0)) {
frequency[place]--;
}
} else if (test == 3) { // third test
if (frequency.indexOf(queries[i][1]) == -1) {
answer.push(0);
} else {
answer.push(1);
}
}
}
return answer;
}
Link: Hackerrank
Task is in category "Dictionaries and Hashmaps". Instead of data and frequency arrays create object with keys being data values and keys being frequencies. Instead of using indexOf which is O(n) you would be doing frequenciesMap[queries[i][1]] which is O(1).

need help understanding using an associative array to keep track of array value appearances

code:
method = function(a) {
//use associative array to keep track of the total number of appearances of a value
//in the array
var counts = [];
for(var i = 0; i <= a.length; i++) {
if(counts[a[i]] === undefined) {
//if the condition is looking for a[0],a[1],a[2],a[3],a[4],a[5] inside counts[] one value at a time and does not find them inside counts[] it will set each value to 1
counts[a[i]] = 1;
console.log(counts[a[i]]);
} else {
return true;
}
}
return false;
}
the js console logs 1x6
how can the condition see if a value inside counts[a[i]] has been repeated if all of the counts[a[i]] values are being set to 1 each iteration? wouldn't it always be comparing 1 to 1?
for example, if the a array is [1,2,3,4,5,2] and counts[a[1]](first int 2 in the array) is undefined and then set to 1, how would the condition know that counts[a[5]](second int 2 in the array) is the same value as counts[a[1]] and therefore it should return true?
perhaps I am misunderstanding whats going on.
I would appreciate any help. thanks
function counter(){
this.counts=[];
}
counter.prototype.add=function(a){
if(this.counts[a] === undefined) {
this.counts[a] = 1;
console.log(this.counts);
} else {
return true;
}
return false;
}
try this:
c= new counter();
c.counts;//[]
c.add(1);
c.counts;//[ ,1]
c.add(5);
c.counts;//[ ,1, , , ,1]
c.add(1);//true
...
may it helps you to understand whats going on

Remove an item from array of items

I have list of variables/items
dbTemp = [Type,Threshold,TypeID,Prioirty,Value,Assign]
where Type,Threshold,TypeID,Prioirty are variables
Let's say, their values are 1,0,2,0,NULL,21
If a variable value is 0 or NULL, I need to remove/exclude them from the list and build a dynamic variable expression based on the non-zero or non-NULL values
In this case, Dynamic Expression = Type>0+TypeID>0+Assign>0 (excludes Threshold, Priority, Value variables since their values are 0 or NULL)
Can you please help me here?
filtered here:
var filtered = dbTemp.filter( function(el) { return !!el; } );
will contain all non null or zero elements from dbTemp;
If you want to filter based on some condition(s) instead of just filtering falsy values:
var filtered = orignalArray.filter(function(item) {
return (item !== condition1) && (item !== condition2);
});
p.s. NULL !== null
If you'll allow for any falsey value and a result that is a filtered copy, then this will suffice:
var result = dbTemp.filter(Boolean);
If you actually need to mutate the original and order doesn't matter, then do this:
for (var i = 0; i < dbTemp.length; i++) {
if (!dbTemp[i]) {
dbTemp[i] = dbTemp[dbTemp.length-1];
dbTemp.length--;
i--;
}
}
If the original order does matter, then this:
for (var i = 0; i < dbTemp.length; i++) {
if (!dbTemp[i]) {
dbTemp[i].splice(i, 1);
i--;
}
}

Javascript checking whether string is in either of two arrays

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.

Explode a string into a hashmap for searching?

I have a string like this being returned from my backend:
"1,2,3,4,5,6"
I have a large array locally and want to display only those items not in this list, so I was thinking of exploding this string into an array but how can I search efficiently? As far as I know there are no hashmaps in JS so how does one do this? I just need to check for key existence.
All Javascript objects are also hash tables that can store string or numeric keys:
var x = {};
x["foo"] = 1;
if("foo" in x) { alert("hello!"); }
if("bar" in x) { alert("should never see this"); }
"1,2,3,4,5,6".split(",").some(function(letter) {
return letter === '2'
});
Warning: Might not work in IE (or other crappy browser)
Cross browser version (that relies on native code for performance):
var arr = "1,2,3,4,5,6".split(",");
if(arr.some)
{
arr.some(function(letter) {
return letter === '2'
});
}
else
{
for(var i = 0 ; i < arr.length ; i++ )
{
if(arr[i] === '2') return true;
}
}

Categories