var klas4 = [];
klas4[2] = [];
klas4[2]["hour"] = 1;
klas4[2]["teacher"] = "JAG";
klas4[2]["group"] = "V4A";
klas4[2]["subject"] = "IN";
klas4[2]["classroom"] = "B111";
klas4[0] = [];
klas4[0]["hour"] = 6;
klas4[0]["teacher"] = "JAG";
klas4[0]["group"] = "V4B";
klas4[0]["subject"] = "IN";
klas4[0]["classroom"] = "B111";
klas4[1] = [];
klas4[1]["hour"] = 4;
klas4[1]["teacher"] = "NAG";
klas4[1]["group"] = "V4A";
klas4[1]["subject"] = "NA";
klas4[1]["classroom"] = "B309";
This multidimensional array needs to be sorted by hour, ascending. The problem is, I don't know how to sort an multidimensional array. The first dimension (0, 1 and 2), needs to be changed, according to the hour, but all other details from dimension 2 (teacher, group etc.) also need to change from index, because otherwise the data is mixed.
You don't know how many indexes there are. In this example, the correct sequence should be: klas4[2][...], klas4[1][...], klas[0][...]
In PHP there's a certain function multisort, but I couldn't find this in jQuery or JavaScript.
klas4.sort( function(a,b){ return a.hour - b.hour } );
should do it.
It helps to think of klas4 not as a multi-array but as 1 array of objects.
Then you sort the objects in that array with a sort function.
The sort function takes 2 objects and you must return which one comes first.
You should read on sort() for Array, google that.
Also, as others have commented; the entries for klas4 are really objects, you should use
klas4[2] = {};
or even better
klas4[2] = { hour:1 , teacher:"JAG" , group:"V4A" , subject: "IN" };
Finally, I assume you are a native Dutch or German speaker, as I am. I would strongly suggest to name all your variables in English, class4, not klas4. It is the right, professional thing to do.
Related
I wanted to know how can we get every alternate object in a array. For EG -
arr = ["foo","bar","foo1","bar1"]
I Need The values -
fir_alt = ["foo","foo1"]
sec_alt = ["bar","bar1"]
If This Helps This Is My Intention -
I am trying to link localstorage and firestore using the js-sdk.. Data is in array and have to take the array to store it back in localstorage.fir_alt would be the keys and sec_alt would be values. So I Can Make it Much More Multi-Device..
Thanks In Advance
You can use the filter function to filter out even and odd index's.
arr = ["foo","bar","foo1","bar1"]
fir_alt = arr.filter((element, index) => index % 2 == 0);
sec_alt = arr.filter((element, index) => index % 2 == 1);
console.log('fir_alt', fir_alt)
console.log('sec_alt', sec_alt)
I'd use an index variable and a loop(for/next or your fav). Examine the index on each iteration of the loop, and determine if the index is odd or even(or 0), then take the appropriate action to capture the desired values.
If I know what you mean... We can be reasoned with odd and even index.
In this way:
let arr = ["foo","bar","foo1", "bar1"],
fir_alt = [],
sec_alt = [];
for (let i=0;i<arr.length;i++){
if ((i+2)%2==0) {
sec_alt.push(arr[i]);
}
else {
fir_alt.push(arr[i]);
}
}
I have an array of arrays in JavaScript that I'm storing some values in, and I'm attempting to find a way to clear the value within that array when the user removes the specified control from the page, however I'm not finding a good way to do this and anything I try doesn't seem to be working.
What is the best method for clearing the value in the array? I'd prefer the value to be null so that it's skipped when I iterate over the array later on.
I've tried to do MyArray[id][subid] = '' but that still is technically a value. I've also tried to do MyArray[id][subid].length = 0 but that doesn't seem to do anything either. Trying to grab the index and splice it from the array returns a -1 and therefore doesn't work either.
var MyArray;
window.onload = function(){
MyArray = new Array();
}
function EditValuesAdd(){
var Input = document.getElementById('Values-Input').value;
var ID = document.getElementById('FID').value;
var ValueID = ControlID(); // generate GUID
if (!MyArray[ID]) MyArray[ID] = new Array();
MyArray[ID][ValueID] = Input;
document.getElementById('Values').innerHTML += '<a href="#" id="FV-' + ValueID + '" onclick="EditValuesRemove(this.id)"/><br id="V-' + ValueID + '"/>';
}
function EditValuesRemove(id)
{
var ID = document.getElementById('FID').value;
document.getElementById(id).remove();
document.getElementById(id.replace('FV-', 'V-')).remove();
MyArray[ID][id.replace('FV-', '')] = '';
}
I've also tried to do an index of and then splice it from the underlying array but the index always returns -1.
var Index = MyArray[ID].indexOf(id.replace('FV-', ''));
MyArray[ID].splice(Index, 1);
Setting the length to zero has no effect either.
MyArray[ID][id.replace('FV-', '')].length = 0;
I would expect that one of the methods above would clear out the value and make it null so that it is skipped later on but all of the methods I've found and tried so far leave some non-null value.
What you need is an object (a Map), not an array (a list).
Here's a basic idea of how to do it :
MyArray = {};
....
if (!MyArray[ID]) MyArray[ID] = {}
MyArray[ID][ValueID] = Input;
...
delete MyArray[ID][id.replace('FV-', '')];
Check here for more information : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
In the end I used an array of objects MyArray = [] and then using splice/findindex to remove it from the array:
function RemoveItem(id)
{
var Index = MyArray.findIndex(a => a.ID == id.replace('FV-', ''));
MyArray.splice(Index, 1);
document.getElementById(id).remove();
document.getElementById('FVB-' + id.replace('FV-', '')).remove();
}
It doesn't solve the actual question asked but I don't know if there really is an answer since I was using arrays in the wrong manner. Hopefully this at least points someone else in the right direction when dealing with arrays and objects.
In Google Earth Engine Developer's Guide, there is a recommendation to avoid for() loops. They recommend to use map() function as this example:
// to avoid
var clientList = [];
for(var i = 0; i < 8; i++) {
clientList.push(i + 1);
}
print(clientList);
// to use
var serverList = ee.List.sequence(0, 7);
serverList = serverList.map(function(n) {
return ee.Number(n).add(1);
});
print(serverList);
I'm trying to select MODIS scenes from each month/year prior to compute VCI. So, the approach I'd take is with a double loop:
modis = ee.ImageCollection("MODIS/MYD13A1");
var modis_list = [];
for(var i = 1; i <13; i++) {
for(var j = 2000; j <2018; j++){
modis_list.push(modis.filter(ee.Filter.calendarRange(i, i, 'month'))
.filter(ee.Filter.calendarRange(j, j, 'year')));
}
}
print(modis_list);
Is there a way to replicate a double loop like this with map() function to reach a server-side approach?
The easy way to do this is with a single map over the "months" you care about.
// Collect images for each month, starting from 2000-01-01.
var months = ee.List.sequence(0, 18*12).map(function(n) {
var start = ee.Date('2000-01-01').advance(n, 'month')
var end = start.advance(1, 'month')
return ee.ImageCollection("MODIS/MYD13A1").filterDate(start, end)
})
print(months.get(95))
This will return a list of ImageCollections. Most months will have only 1 image, since MYD13A1 contains 16-day images, but some will have two. Month 95 is Jan of 2008 and has two.
Alternatively, you could join the collection with a collection of dates, but this is simpler.
And you should prefer filterDate over calendarRange when possible, as it's optimized.
Assuming that you are just trying to understand GEE's map() function, and how would be the equivalent of a normal js for loop, the code would be:
var map_m = function(i) {
i = ee.Number(i)
var years = ee.List.sequence(2000, 2017)
var filtered_col = years.map(function(j) {
var filtered = modis.filter(ee.Filter.calendarRange(i, i, 'month'))
.filter(ee.Filter.calendarRange(j, j, 'year'))
return filtered
})
return filtered_col
}
var months = ee.List.sequence(1, 12)
var modis_list2 = months.map(map_m).flatten()
This code replicates a normal for loop. First, it goes item by item of the years list, and then item by item of the months list, and then, once you have year and month, filter the collection and add it to a list (map does that automatically). As you use 2 map functions (one over years and the other over months), you get a list of lists, so to get a list of ImageCollection use the flatten() function. Somehow the printed objects are a bit different, but I am sure the result is the same.
Let me start by saying I know nothing about Google Earth Engine and my info is from functional programming knowledge.
map is unique in that it doesn't generate the things it loops over. You start with a list and map iterates over each item in that list and transforms it. If you don't have that list then map isn't a great fit.
It looks like you are creating a list with each month/year combo represented. I would break this into a few steps. Build the month and year lists, build the list that represents cartesian product of the 2 lists then transform to the ee objects.
var range = (from, to) => new Array(end-start+1).fill(0).map((_,i)=>i+from)
var cartesianProduct = (a, b) => // not gonna do this here but it returns pairs [ [ a[1], b[1] ], ... ]
var getEE = ([month, year]) => modis
.filter(ee.Filter.calendarRange(month, month, 'month'))
.filter(ee.Filter.calendarRange(year, year, 'year'));
var months = range(1,12);
var years = range(2000, 2017);
var data = cartesianProduct(months, years)
.map(getEE)
There are likely better ways(like not iterating throught the whole list of modis each time we want a single month object (use a dictionary)) but the gist is the same.
I have an Array with 12 Entries. I like to sort them by titles. Many of articles have the same titles, and i could be easy, because title are identical.
i could be probably 3 or 4 groups at the end.
i have very tiny javascript code, because i dont know if i want to do it with loop or some other way.
Javascript
var totalGroups = [];
var actualGroup = [];
var contentarticles = articles.contentarticles,
article,
$out = $("#articlesOutput");
for (var i = 0; i < contentarticles.length; i++) {
if (!article || article.title != contentarticles[i].title) {
article = contentarticles[i];
document.getElementById('articleForNaviTopTitle').innerHTML = article.title;
document.getElementById('articleForNaviTopID').innerHTML = article.id;
var articlesOutput = [
'<li><a href="./certifiedTraining/id=', article.id, '/step=', i + 1, '">',
article.title,
'</li>'
].join("");
$out.append(articlesOutput);
}
}
// till this point all works fine, and a code above gives results in the image below.
//**Im struggeling right there, how to sort this array by groups?????**
while (article.title(this) == article.title(next))
{
code block to be executed
}
If I understood correctly what you want is to pick out every object and sort them in groups by title. If I were you I'd take a look at UnderScore js. It is a nice collection of utilities for js.
var grouped = _.groupBy(yourObjects, 'title');
Not sure if I understand what you mean about "sorting array by groups". Let's say you want to sort an array by title; then you will have something like:
contentarticles.sort(function(a, b) {
if (a.title > b.title) return 1;
if (a.title < b.title) return -1;
return 0;
});
But if this is not the result you want, could you be more explicit? What do you want do to exactly, filter out the duplicates? Creates "array of array"? Or what?
If you want to group instead of sort:
var articles = contentarticles.reduce(function(articles, article) {
(articles[article.title] || (articles[article.title] = [])).push(article);
return articles;
}, {});
In this way you will have an object where the properties are the title it self, an each property will contains an array with the full article object. So, once you have the title, you can obtain all the articles with the same title. If you want a list of all titles, you can use Object.keys; where if you want to iterate you can use for…in.
Here the reduce method I used.
I'm trying to break up a string like this one:
fname=bill&mname=&lname=jones&addr1=This%20House&...
I want to end up with an array indexed like this
myarray[0][0] = fname
myarray[0][1] = bill
myarray[1][0] = mname
myarray[1][1] =
myarray[2][0] = lname
myarray[2][1] = jones
myarray[3][0] = addr
myarray[3][1] = This House
The url is quite a bit longer than the example. This is what I've tried:
var
fArray = [],
nv = [],
myarray = [];
fArray = fields.split('&');
// split it into fArray[i]['name']="value"
for (i=0; i < fArray.length; i++) {
nv = fArray[i].split('=');
myarray.push(nv[0],nv[1]);
nv.length = 0;
}
The final product is intended to be in 'myarray' and it is, except that I'm getting a one dimensional array instead of a 2 dimensional one.
The next process is intended to search for (for example) 'lname' and returning the index of it, so that if it returned '3' I can then access the actual last name with myarray[3][1].
Does this make sense or am I over complicating things?
Your line myarray.push(nv[0],nv[1]); pushes two elements to the array myarray, not a single cell with two elements as you expect (ref: array.push). What you want is myarray.push( [nv[0],nv[1]] ) (note the brackets), or myarray.push(nv.slice(0, 2)) (ref: array.slice).
To simplify your code, may I suggest using Array.map:
var q = "foo=bar&baz=quux&lorem=ipsum";
// PS. If you're parsing from a-tag nodes, they have a property
// node.search which contains the query string, but note that
// it has a leading ? so you want node.search.substr(1)
var vars = q.split("&").map(function (kv) {
return kv.split("=", 2);
});
For searching, I would suggest using array.filter:
var srchkey = "foo";
var matches = vars.filter(function (v) { return v[0] === srchkey; });
NB. array.filter will always return an array. If you always want just a single value, you could use array.some or a bespoke searching algorithm.
for (var i = 0; i < fArray.length; i++) {
nv = fArray[i].split('=');
myarray.push([nv[0],nv[1]]);
}
nv.length = 0; is not required, since you're setting nv in each iteration of the for loop.
Also, use var i in the for-loop, otherwise, you're using / assigning a global variable i, that's asking for interference.