How to handle an dynamic array? - javascript

I want to show up the names of the members of an array "path" in my console.
console.log("start: ", path[0].name, "second: ", path[1].name, "third: ", path[2]name, ....)
But the problem is, that my array always changes it's size (clicking algorithm), that means sometimes it has the lenght 4 or sometimes 8 ect.
How can i adjust the console.log code to this dynamic array?
Thanks so much!

Try
path.forEach((each, i)=>{
console.log ("item" + i+ ':' + each.name );
})

Something like this:
var path = ['Prit', 'Bab', 'Nav']
var item = ["first","second", "third"];
for (i = 0; i < path.length;i++){
console.log(item[i] + ":" + path[i])
}

Try something like this for single line result set ...
var result = "";
for (var i = 0, len = path.length; i < len; i++) {
if (i !== 0) {
result += ", ";
}
result += (i + 1) + ": " + path[i].name;
}
console.log(result);

you could use a for loop here , ie,
for (var i=0;i<path.length;i++) {
console.log("item no "+ i +": " + path[i]);
}

/* Console Array */
var consoleArray = new Array;
/* Names */
var path = [
{name: 'bob'},
{name: 'jimmy'},
{name: 'chris'},
{name: 'alexander'},
{name: 'mark'}
];
/* Loop */
for(var i = 0; i < path.length; i++) {
consoleArray.push((i + 1) + ': ' + path[i].name);
}
/* Console Log */
console.log(consoleArray.join("\n"));

With ES6, you could use spread syntax ....
var path = [{ name: 'Jo'}, { name: 'John'}, { name: 'Jane'}];
console.log(...path.map((a, i) => (i ? i + 1 : 'Start') + ': ' + a.name));

Related

Looping over JavaScript object and adding string to end if not the last item

{
field_country: ["England", "Netherlands", "India", "Italy"],
field_continent: ["Europe"],
field_group: ["Building", "People", "Landscape"
}
I want to loop over each item and return the key and the array together with ending 'OR' for example:
field_country: "England" OR field_country: "Netherlands"
The last item should not end with 'OR' in the loop. I am not sure what the best process is for this using vanilla JS. So far my code is as follows:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i == 1) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I would be very grateful for any assistance.
Thanks in advance.
You can do something like this with Object.entries and Array.reduce if you would like to get the final result in the form of an object:
const data = { field_country: ["England", "Netherlands", "India", "Italy"], field_continent: ["Europe"], field_group: ["Building", "People", "Landscape"] }
const result = Object.entries(data).reduce((r, [k, v]) => {
r[k] = v.join(' OR ')
return r
}, {})
console.log(result)
It is somewhat unclear what is the final format you need to result in but that should help you to get the idea. If ES6 is not an option you can convert this to:
const result = Object.entries(data).reduce(function(r, [k, v]) {
r[k] = v.join(' OR ')
return r
}, {})
So there are is no arrow function etc.
The idea is to get the arrays into the arrays of strings and use the Array.join to do the "replacement" for you via join(' OR ')
Here's the idea. In your code you are appending " or " at the end of your strings starting at index 0. I suggest you append it at the the beginning starting at index 1.
var somewords = ["ORANGE", "GREEN", "BLUE", "WHITE" ];
var retval = somewords[0];
for(var i = 1; i< somewords.length; i++)
{
retval += " or " + somewords[i];
}
console.log(retval);
//result is: ORANGE or GREEN or BLUE or WHITE
Your conditional expression if (i == 1) would only trigger on the second iteration of the loop since i will only equal 1 one time.
Try something like:
if (i < (facetResults.length - 1)) {
// only add OR if this isn't the last element of the array
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
}
Here's your updated code:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i < (facetResults.length - 1)) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});

How to remove empty values from array in google docs script

I am trying to print out the values of the array in a google doc. I do get the correct values but it goes on printing out a number of "undefined" values. The simplest way is probably to filter out the undefined values before I print out the array.
Here is the array declaration:
var paramArr = Object.keys(e.parameter).reverse();
var tableArr = [];
for(var i = 0; i < paramArr.length - 1; i++) {
var tempArr;
var nameSelector = "Company:" + i;
var startDateSelector = "Started:" + i;
var endDateSelector = "Ended:" + i;
var referenceSelector = "Reference:" + i;
var descriptionSelector = "Description:" + i;
tempArr = [e.parameter[nameSelector] + " ",
e.parameter[startDateSelector] + " - " +
e.parameter[endDateSelector]+ "\n\n" +
e.parameter[descriptionSelector]
];
I have tried this, but it doesn't work:
tempArr = tempArr.filter(function(element){
return element !== undefined;
});

Set interval in a nested loop

I have a nested loop in a function which takes a while to load on IE8 and results in an unresponsive page.
I have a loading bar which 'freezes' when the script is running.
How can I use setInterval() to stop processing JS after each iteration to make it appear the loading bar is still moving and make it appear that the page is responsive?
The function is:
function createDropDown() {
var target = $('#mainList');
for (var i = 0; i < info.books.length; i++) {
var gnrval = info.books[i].genre
var catval = info.books[i].category
for (var j = 0; j < info.books[i].publishers.length; j++) {
var pubval = info.books[i].publishers[j].publisher
if (typeof app.cache.pub[pubval] == 'undefined') {
app.cache.pub[pubval] = {
'ul': $('<li class="publisher" data-value="' + pubval + '">' + pubval + '<ul class="sub-menu" data-title="Publishers"></ul></li>').appendTo(target).children('ul'),
'aut': {}
};
}
var ulauthors = app.cache.pub[pubval].ul;
for (var k = 0; k < info.books[i].publishers[j].authors.length; k++) {
var autval = info.books[i].publishers[j].authors[k].name + ' (' + gnrval + ')'
var aut_val = info.books[i].publishers[j].authors[k].name
if (typeof app.cache.pub[pubval].aut[autval] == 'undefined') {
app.cache.pub[pubval].aut[autval] = $('<li class="author" data-value="' + autval + '">' + autval + '<ul class="sub-menu" data-title="Authors"></ul></li>').appendTo(ulauthors).children('ul')
}
var ulyears = app.cache.pub[pubval].aut[autval]
console.log(ulyears)
var gItems = []
for (var m = 0; m < info.books[i].publishers[j].authors[k].yearsPublished.length; m++) {
var yearval = info.books[i].publishers[j].authors[k].yearsPublished[m]
var year = ulyears.find('.year[data-value="' + yearval + '"]')
if (year.size() == 0) {
var id = ++count
gItems.push('<li class="year" data-value="' + yearval + '"><a id="selyear' + id + '" class="addone" data-id="' + id + '" data-year="' + yearval + '" data-pub="' + pubval + '" data-aut="' + aut_val + '" data-cat="' + catval + '" data-gnr="' + gnrval + '">' + yearval + '</a></li>')
}
}
ulyears.append(gItems.join(''))
};
};
};
I tried adding:
setTimeout(function () {
//last nested loop code here
timeout();
}, 1000);
But obviously it didn't work.
You should start by breaking this gigantic function down. Simple tip: Principle of single responsibility.
Nesting loops squares the number of operations done. I suggest simplifying your data so that it can be done in one loop or a series of loops, and not nested loops. This would mean unnesting the data or structuring it in a way that you can simply do one pass.
A caveat is that the data will multiply in size, so it's a tradeoff between payload size and processing performance. Here's an example, where a case of locating the "geo" book would take several searches on the first data structure, but would only be a simple filter on the second data structure.
// So you loop through the properties of books, then another loop through math
// then another loop through science, then you get your "geo". Loops: 3
{
books : {
math : ['algebra','trigo','solids'],
science : ['bio','geo','psycho']
}
}
// Here, var geoBook = array.filter(function(book){return book.topic === 'geo'})[0];
// Loops: 1 (filter is essentially a loop)
[
{
type : 'book',
subject : 'math',
topic : 'algebra'
},{
type : 'book',
subject : 'math',
topic : 'trigo'
},{
type : 'book',
subject : 'math',
topic : 'solids'
},{
type : 'book',
subject : 'science',
topic : 'bio'
},{
type : 'book',
subject : 'science',
topic : 'geo'
},{
type : 'book',
subject : 'science',
topic : 'psycho'
},
]
To avoid freezing the browser, you need to "defer" operations using timers. You can use setInterval with a counter instead of loops. Here's a simple example:
function each(array,iterator){
var i = 0, length = array.length;
var timer = setInterval(function(){
iterator.call(array,array[i]);
if(++i >= length) clearInterval(timer);
},1000);
}
each([1,2,3,...10000],function(n){
console.log(n);
})

How do i stop my array info from printing twice?

I have an array of objects
var event1Array {
name: wedding;
time: ["10:00am", "12:00pm"];
}
var event2Array {
name: housewarming;
time: ["7:00pm", "9:00pm"]
}
var eventArray = [event1Array, event2Array];
I want to loop through using just two loops (inner and outer) using an alert like this
alert("attend a " + eventArray.name + " starting " + theEvent.time)
But my event info keeps printing twice like
attend a wedding starting 10am,
attend a wedding starting 12pm
attend a housewarming starting 7pm
attend a housewarming starting 9pm
here's the complete code
var event1Array
{
name: wedding;
time: ["10:00am", "12:00pm"];
}
var event2Array
{
name: housewarming;
time: ["7:00pm", "9:00pm"];
}
var div = document.getElementById("events");
var eventArray = [event1Array, event2Array];
for (var i = 0; i < eventArray.length; i++)
{
var theEvent = eventArray[i];
for (j = 0; j < theEvent.time.length; j++)
{
console.log("Attending a wedding" + theEvent.name + "starting" + theEvent.time[j]);
}
}
They aren't Arrays. event1Array and event2Array are actually Objects, so you don't want to loop through them. You should only be looping through the eventArray.
for (var i = 0, len = eventArray.length; i < len; i++) {
alert("attend a " + eventArray[i].name + " starting " + eventArray[i].time[0]);
}
Here is a working jsfiddle...
try this
alert("attend a " + eventArray.name + " starting " + theEvent.time[0])

Javascript 'undefined' when using a function variable on an array of objects

I have the following (example) array of objects:
var theArray = [
{theId:'1', num: 34},
{theId:'2', num: 23},
{theId:'5', num: 26}
];
and this function, which works fine to loop through them:
function printValues() {
var i = 0;
for(i; i<theArray.length; i++) {
var obj = theArray[i];
document.getElementById('result1').innerHTML += obj.theId + ' = ' + obj.num + '<br>';
}
}
However, if I want to abstract this function for use on similar arrays by using function variables to access objects within them, like this:
function printValuesVar(arr,elemId,arrId,arrNum) {
var i = 0;
for(i; i<arr.length; i++) {
var obj = arr[i];
document.getElementById(elemId).innerHTML += obj.arrId + ' = ' + obj.arrNum + '<br>';
}
}
'undefined' is the result when called as below (as I'd kind of expect since 'arrId' is not an object name):
printValuesVar(theArray,'result2','theId','num');
How can I use the values passed to the function's variables to access values of objects within the array by name?
rewritten following advice against antipatterns:
function printValuesVar(arr,elemId,arrId,arrNum) {
var i = 0;
var content = '';
for(i; i<arr.length; i+=1) {
var obj = arr[i];
content += obj[arrId] + ' = ' + obj[arrNum] + '<br>';
}
document.getElementById(elemId).innerHTML = content;
}
Try this:
function printValuesVar( arr, elemId, arrId, arrNum ) {
var content = '';
arr.forEach( function ( arrElem ) {
content += arrElem[ arrId ] + ' = ' + arrElem[ arrNum ] + '<br>';
});
document.getElementById( elemId ).innerHTML = content;
}
Or a bit more advanced:
function printValuesVar( arr, elemId, arrId, arrNum ) {
document.getElementById( elemId ).innerHTML = arr.map( function ( arrElem ) {
return arrElem[ arrId ] + ' = ' + arrElem[ arrNum ];
}).join( '<br>' );
}
ES5-shim for shitty browsers
Because you are loking for key "arrId", not the key stored in variable arrId
document.getElementById(elemId).innerHTML += obj[arrId] + ' = ' + obj[arrNum] + '<br>';

Categories

Resources