JavaScript for loop closure issue - javascript

I am adding all categories after ticking them to true if they exists in selected categories of result but it combines previous categories results with current one. I tried closure but it doesn't give me fresh object. Check out fiddle.
var allCatsResult = [{"id":1},{"id":2}, {"id":3}, ... ];
var catsArray = [1, 2] // Array of ids from allCatsResult
var result = [
{"id":1, selectedCategories:[{"id":1},{"id":2}]},
{"id":2, selectedCategories:[{"id":4},{"id":5}]},
...
];
for (var i = 0; i < results.length; i++) {
var tmp = allCatsResult; // tried to add function form here didn't work
for (var k = 0; k < results[i].selectedCategories.length; k++) {
var index = catsArray.indexOf(results[i].selectedCategories[k].category_id);
if(index !== -1) {
tmp[index].ticked = true;
}
}
results[i].categories = tmp;
}
Above code gives combined result for ticked = true for all categories in each result.

You need to copy/clone the array of objects, or you're manipulating the original. There are a few ways apparently. I chose the following:
var tmp = JSON.parse(JSON.stringify(allCatsResult));
This will create a new array of objects in tmp, and it will correctly only modify the clone.

Related

Looping through Json and appending to object

I have this JSON response from Google Maps, saved to a .json file. It's a search for schools nearby.
I only want to extract the name and the location of the schools, and save these to the elemSchoolsArr variable for use later.
I don't know why the code I have below doesn't loop through the json response, checking elemSchoolsObj only show one object, instead of 10, which I would want to push to the elemSchoolsArr later.
var elemSchoolsArr = [];
var elemSchoolsObj = {};
$.getJSON('elementary-schools.json', function(data){
for (var i = 0; i < 10; i++) {
elemSchoolsObj.title = data.results[i].name;
elemSchoolsObj.location = data.results[i].geometry.location;
}
});
elemSchoolsArr.push(elemSchoolsObj);
You just need to push the object in to the array inside of the loop, so that each object is pushed in, rather than just one. Obviously this code snippet won't actually run because we're not getting your JSON here.
var elemSchoolsArr = [];
$.getJSON('elementary-schools.json', function(data){
for (var i = 0; i < 10; i++) {
var elemSchoolsObj = {};
elemSchoolsObj.title = data.results[i].name;
elemSchoolsObj.location = data.results[i].geometry.location;
elemSchoolsArr.push(elemSchoolsObj);
}
});
Here's a functional example...
var array = ["a", "b", "c", "d", "e"];
var first_try = [];
var second_try = [];
for( var i = 0; i < array.length; i++ ){
// we define our object in the loop but don't add it to the array
var obj = {
item: array[i]
};
}
// we push one object in to the array
first_try.push( obj );
// we get one object in the array
console.log( first_try );
for( var i = 0; i < array.length; i++ ){
// we define our object in the loop
var obj = {
item: array[i]
};
// we push each object we define in the loop in to the array
second_try.push( obj );
}
// we get all the objects in the array
console.log( second_try );

How to generate an array with repeated string javascript

How to generate an array with function like this?
var name = ["monkey","monkey"..."horse","horse",..."dog","dog",..."cat","cat"...]​
In my real case, I may have to repeat each name 100 times..
Assuming that you already have that words in a array try this code:
var words = ["monkey", "hourse", "dog", "cat"];
var repeatWords = [];
for(var i = 0; i < words.length; i++)
{
for(var j = 0; j < 100; j++)
{
repeatWords.push(words[i]);
}
}
You can try this, specifying the words to be used, and the times to create the array you need.
var neededWords = ["Cat", "Hourse", "Dog"];
var finalArray = [];
var times = 10;
for (var i = 0; i < neededWords.length; i++) {
for (var n = 0; n < times; n++) {
finalArray.push(neededWords[i]);
}
}
console.log(finalArray);
Hope that helps!
If I understood correctly you need a function that takes as an argument a collection of items and returns a collection of those items repeated. From your problem statement, I assumed that the repetition has to be adjusted by you per collection item - correct me if I am wrong.
The function I wrote does just that; it takes an object literal {name1:frequency1,name2:frequency2..} which then iterates over the keys and pushes each one as many times as indicated by the associated frequency in the frequencyMap object.
function getRepeatedNames( frequencyMap ) {
var namesCollection = [];
Object.keys(frequencyMap).forEach(function(name,i,names){
var freq = frequencyMap[name];
freq = (isFinite(freq)) ? Math.abs(Math.floor(freq)) : 1;
for (var nameCounter=0; nameCounter<freq; nameCounter++) {
namesCollection.push(name);
}
});
return namesCollection;
}
Non-numeric values in the frequency map are ignored and replaced with 1.
Usage example: If we want to create an array with 5 cats and 3 dogs we need to invoke
getRepeatedNames({cat: 2, dog: 3}); // ["cat","cat","dog","dog","dog"]

How to access array within an object within an array?

I have both an object and an array:
var elementsArr = [];
var elements = {
polygon: 734,
infoContent: "huhu",
id: 0
}
I am going to have multiple "elements" and push each one into "elementsArr".
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsArr.push(elements);
}
My problem now is how to access a specific "id" within the object elements, within the array elementsArr and pushing this into another array.
I tried this but it doesn't seem to be working:
var ids = [];
for(var m=0; m<elementsArr.length; m++){
if(elements.id == elementsArr[m]){
ids.push(elements.id);
}
How do I do this?
Your code is pushing the same object onto the array over and over again.
One way to fix that would be to write a function to get a new element:
function Element(id) {
return {
polygon: 734,
infoContent: "huhu",
id: id
};
}
for(var i=0; i<20; i++){
elementsArr.push(Element(i));
}
If there are going to be a lot of elements, and the "id" values are all relatively small numbers, you'd be better off storing the elements such that the "id" is also the index:
for (var i = 0; i < 20; i++)
elementsArr[i] = Element(i);
To get the element with "id" 17, then:
var element17 = elementsArr[17];
If you really want to search, however, you can use .find():
var element17 = elementsArr.find(function(elem) { return elem.id === 17; });
or a simple loop:
for (var i = 0; i < elementsArr.length; ++i) {
if (elementsArr[i].id === 17) {
// found it!
}
}
You can extract the "id" values from the array with a simple call to .map():
var ids = elementsArr.map(function(elem) { return elem.id; });
or another for loop:
var ids = [];
for (var i = 0; i < elementsArr.length; ++i)
ids.push(elementsArr[i].id);
There are a couple of ways to do this. If you are able to work in ES6 then a WeakMap would be great.
However, I'm going to give you an ES5 instead.
Option 1 Loop through the data.
If you aren't accessing the data often, then looping through as you've done so may be the best choice.
Option 2 Set up your own index
On the other hand, if you need faster lookup, you can set up your own separate index to look things up.
var elementsLookup = {}; // Create an empty object.
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsLookup[id] = elements; // Stash off a copy
elementsArr.push(elements);
}
Then you can look things up with a
var elem = elementsLookup[2]; // Get the element with an id of 2.
It is easy to do it with Array prototyping. Here is a function findById
Array.prototype.findById = function(id){
for(var x = 0 ; x < this.length; x++){
if(this[x].id == id){
return this[x];
}
}
return false;
}
You can use this function to recieve any id from the array or false if it does not exists
elementsArr.findById(17);

Javascript arrays storing values

There might be a very simple solution my problem but just not being able to find one so please help me to get to my solution in the simplest way...
The issue here is that I have data being displayed in a tabular form. Each row has 5 columns and in one of the columns it shows multiple values and so that's why I need to refer to a value by something like this row[1]['value1'], row[1]['value2'] & then row[2]['value1'], row[2]['value2'].
I declare the array
var parray = [[],[]];
I want to store the values in a loop something like this
for(counter = 0; counter < 10; counter ++){
parray[counter]['id'] += 1;
parray[counter]['isavailable'] += 0;
}
Later I want to loop through this and get the results:
for (var idx = 0; idx < parray.length; idx++) {
var pt = {};
pt.id = parray[schctr][idx].id;
pt.isavailable = parray[schctr][idx].isavailable;
}
Obviously iit's not working because Counter is a numeric key and 'id' is a string key ..my question how do I achieve this ??
Thanks for all the answers in advance.
JS has no concept of "associative arrays". You have arrays and objects (map). Arrays are objects though, and you can put keys, but it's not advisable.
You can start off with a blank array
var parray = [];
And "push" objects into it
for(counter = 0; counter < 10; counter++){
parray.push({
id : 1,
isAvailable : 0
});
}
Then you can read from them
for (var idx = 0; idx < parray.length; idx++) {
// Store the current item in a variable
var pt = parray[idx];
console.log(pt);
// read just the id
console.log(parray[idx].id);
}
Like I did here
What you want inside your array is just a plain object:
// just a regular array
var parray = [];
for(var counter = 0; counter < 10; counter++){
// create an object to store the values
var obj = {};
obj.id = counter;
obj.isavailable = 0;
// add the object to the array
parray.push(obj);
}
later:
for (var idx = 0; idx < parray.length; idx++) {
var pt = parray[idx];
// do something with pt
}

JavaScript: assigning to array in nested loops

I'm working on a codecademy.com lesson on arrays. I'm supposed to write nested loops to put each card of every suit in a deck of cards in an array.
I'm really messing this up. This is one combination that I've tried that doesn't work. The only indication that I have that I'm sort of close is that it returns "52" so at least 52 objects are going into the array. can anyone point out what I'm doing wrong?
//array 1: the suits
var suits = ["clubs","hearts","diamonds","spades"];
//array 2: the ranks
var ranks = [2,3,4,5,6,7,8,9,10,"J","Q","K","A"];
//using for loops, modify the "deck" array so that it becomes a
//two-dimensional array that stores every card in the deck;
//e.g. [1, "clubs"], [2, "clubs"],etc...["A", "spades"]
var deck = [];
for(i = 0; i < suits.length; i++){
for (j = 0; j < ranks.length; j++){
var cardArray = [];
cardArray[0] = suits[i];
cardArray[0][0] = ranks[j];
deck.push(cardArray);
}
}
Each iteration, a new array is being added to deck that looks like the following:
cardArray: [ [ ranks[j] ] ]
When cardArray[0][0] is set, it is overwriting cardArray[0] as an array with index 0 containing ranks[j]. Instead, set cardArray[0] to suits, and cardArray[1] to ranks.
cardArray[0] = suits[i];
cardArray[1] = ranks[j];
deck.push(cardArray);
This results in:
for (var i = 0; i < suits.length; i++){
for (var j = 0; j < ranks.length; j++){
var cardArray = [];
cardArray[0] = suits[i];
cardArray[1] = ranks[j];
deck.push(cardArray);
}
}
You should use a var declaration for your loop counter. Your problematic code is
cardArray[0] = suits[i];
cardArray[0][0] = ranks[j];
which does things like
var foo = "clubs";
foo[0] = "J";
which obviously does not work. I think what you want is
var deck = [];
for(var i = 0; i < suits.length; i++){
var cardArray = [];
for (j = 0; j < ranks.length; j++){
var twoCards = [];
twoCards[0] = suits[i];
twoCards[1] = ranks[j];
cardArray.push(twoCards);
// // or the same thing as this loop body, shorter:
// cardArray.push([suits[i], ranks[j]]);
}
deck.push(cardArray);
}

Categories

Resources