There is an array that contains key value pairs which the key will contain a manipulative id. The problems is that I intend to achieve a concept of checking the key values which is if the key is exist in the array, then the value will check; or else it will create a new key value pairs for the new and unique id. I looked for the Object.keys() function and i find out it will only return array of keys. I tend to check the keys one by one in a for loop tho.
sorry if I did not explain my question well
code:
var marks = new Array();
function totalScore(critId,score){
var compare = Object.keys(marks);
var result = 0;
for(var i = 0; i < marks.length; i++){ //Looping in marks array
for(var j = 0; j < compare.length; j++){ //Looping in compare array
if(compare[j] == marks[i]){ //Comparing the key of the arrays
marks[i] = score; //If matched update the value of the current key
result ++;
}
}
if(result == 0){ //If there are no result of the comparison
marks.critId = score; //Add new key value pair to the array
}
}
}
If I understand your problem correctly, you want to add a new key/value pairs if it doesn't exist.
It's better to use an object or an ES6 Map for this case.
var marks = {};
function totalScore(critId, score) {
if(!(critId in marks)) marks[critId] = score;
}
totalScore(1, 5);
totalScore(2, 8);
totalScore(1, 4);
console.log('marks', marks);
Related
I am writing a program that needs to compare different birthday dates in an array, and the array is like this:
birthdays = [1, [11,2], 2, [2,4], 3, [11,2], 4, [3,5], 5, [6,7], 6, [3,5], 7, [8,9]..]
The even index stores the number of student, and the odd positions store their birthday date in the form of an array[month, day]. I need to return an array of number of students who have unique birthday dates(their birthday dates only appeared once in the array).
Here is my effort so far:
function find(birthdays) {
let array2 = birthdays.slice();
let unique_arr = [];
let element_comp;
for (let i = 0; i < birthdays.length; i++) {
birthdays.splice(i,1)//birthdays
array2.splice(i+1,1)//numbers
}
for(let i = 0; i < birthdays.length; i++){
element_comp = birthdays[i];
for(let j = 0; j < birthdays.length; j++){
if(i !== j &&element_comp.toString == birthdays[j].toString){
break;
}
if(j === birthdays.length - 1){
unique_arr.push(array2[i])
}
}
}
return unique_arr;
}
My idea is to break the array into to two sub-arrays, one stores the numbers and the other one stores the birthday dates. Then I compared the element of the birthday date array one by one to see if they are unique. If I find a same date, I break out of the inner and start to compare the next one, otherwise if the inner index reaches the end of the array I stores the element of the number array of the same index into another array that will be returned
Expected Result:[2, 5, 7...]
But it didn't work as expected because it would break out of the array each time and never store the element. Please explain to me where I did wrong, thank you
You can do it with dictiory. without having nested loop
loop on element and see if month and date combination month_date exist in dict append the students to it else create a new key with month_date and append to dict with value of array of current student
after this loop complete you can loop over dict key values and and see if any key having single value then take those values.
function find(birthdays) {
let unique_dates = {}
for (let i = 0; i < birthdays.length; i+=2) {
let key = `${birthdays[i+1][0]}_${birthdays[i+1][1]}`
if (!(key in unique_dates)) {
unique_dates[key] = []
}
unique_dates[key].push(birthdays[i])
}
let unique_arr = [];
for (let unique_date in unique_dates){
if (unique_dates[unique_date].length == 1) {
unique_arr.push(unique_dates[unique_date][0])
}
}
return unique_arr;
}
I had to remove same data in array.
I found this code and its work exactly the way i want but I can not understand part of this code.
please explain this code and WHAT IS THIS >>> a[this[i]] <<<
Array.prototype.unique = function() {
var a = {}; //new Object
for (var i = 0; i < this.length; i++) {
if (typeof a[this[i]] == 'undefined') {
a[this[i]] = 1;
}
}
this.length = 0; //clear the array
for (var i in a) {
this[this.length] = i;
}
return this;
};
Please see the comments before each line that explain that line of code
//added unique function to prototype of array so that all array can have unique //function access
Array.prototype.unique = function() {
//creating a temp object which will hold array values as keys and
//value as "1" to mark that key exists
var a = {}; //new Object
//this points to the array on which you have called unique function so
//if arr = [1,2,3,4] and you call arr.unique() "this" will point to
//arr in below code iterating over each item in array
for (var i = 0; i < this.length; i++) {
//idea is to take the value from array and add that as key in a so
//that next time it is defined. this[i] points to the array item at
//that index(value of i) //and a[this[i]] is adding a property on a
//with name "this[i]" which is the value //at that index so if value
//at that index is lets say 2 then a[this[i]] is //referring to
//a["2"].thus if 2 exists again at next index you do not add it to a
//again as it is defined
if (typeof a[this[i]] == 'undefined') {
a[this[i]] = 1;
}
}
this.length = 0; //clear the array
//now in a the properties are unique array items you are just looping
//over those props and adding it into current array(this) in which
//length will increase every //time you put a value
for (var i in a) {
this[this.length] = i;
}
//at the end returning this which is the modified array
return this;
};
//Edit
stored value of a[this[i]] is 1 for all the keys in a it will be one.
you start with
arr = [1,2,3,2,3,4];
when you call arr.unique
the code in the first loop creates a something like this
a = {
"1":1,
"2":1,
"3":1,
"4":1
}
so you can see that only unique values are as properties in a.
Now in the for-in loop you are just taking the keys of a(ie 1,2,3,4) and adding it to the array(this).
Hope this helps let me know if you need more details
a[this[i]] =>
this[i] -> get i element from current object, in this case it's Array.
a[] -> get element from var a at position specified in [], in this case what value is inside this[i]
I am trying to sort a hashtable (originally called "resultVal") alphabetically in javascript.
// initializing an array with all the keys. //
var keys = [];
// populating it with all the keys in the hashtable. //
for (var key in resultVal) {
if (resultVal.hasOwnProperty(key)) {
keys.push(key);
}
}
// Alphabetically sorting the array populated with hash table keys. //
keys.sort();
var temp = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = resultVal[key];
if (key != "") {
temp[key].push(value);
}
}
My issue is with the last statement :-
temp[key].push(value);
What I am doing is, sort the keys alphabetically and re-feed the key and its respective values into a temp hashtable..."temp".
The push statement isn't being recognized. can anyone help?
temp is defined as an object, not an array. There's no need to push() onto it:
temp[key] = value;
suppose I do..
var arr = Array();
var i = 3333;
arr[i] = "something";
if you do a stringify of this array it will return a string with a whole bunch of undefined numeric entries for those entries whose index is less than 3333...
is there a way to make javascript not do this?
I know that I can use an object {} but I would rather not since I want to do array operations such as shift() etc which are not available for objects
If you create an array per the OP, it only has one member with a property name of "333" and a length of 334 because length is always set to be at least one greater than the highest index. e.g.
var a = new Array(1000);
has a length of 1000 and no members,
var a = [];
var a[999] = 'foo';
has a length of 1000 and one member with a property name of "999".
The speedy way to only get defined members is to use for..in:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var p in a) {
if (a.hasOwnProperty(p) && re.test(p)) {
s.push(a[p]);
}
}
return '' + s;
}
Note that the members may be returned out of order. If that is an issue, you can use a for loop instead, but it will be slower for very sparse arrays:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var i=0, iLen=a.length; i<iLen; i++) {
if (a.hasOwnProperty(i)) {
s.push(a[i]);
}
}
return '' + s;
}
In some older browsers, iterating over the array actually created the missing members, but I don't think that's in issue in modern browsers.
Please test the above thoroughly.
The literal representation of an array has to have all the items of the array, otherwise the 3334th item would not end up at index 3333.
You can replace all undefined values in the array with something else that you want to use as empty items:
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'undefined') arr[i] = '';
}
Another alternative would be to build your own stringify method, that would create assignments instead of an array literal. I.e. instead of a format like this:
[0,undefined,undefined,undefined,4,undefined,6,7,undefined,9]
your method would create something like:
(function(){
var result = [];
result[0] = 0;
result[4] = 4;
result[6] = 6;
result[7] = 7;
result[9] = 9;
return result;
}())
However, a format like that is of course not compatible with JSON, if that is what you need.
I have thousands of legacy code that stores array information in a non array.
For example:
container.object1 = someobject;
container.object2 = someotherobject;
container.object3 = anotherone;
What I want to have is:
container.objects[1], container.objects[2], container.objects[3] etc.
The 'object' part of the name is constant. The number part is the position it should be in the array.
How do I do this?
Assuming that object1, object2, etc... are sequential (like an array), then you can just iterate through the container object and find all the sequential objectN properties that exist and add them to an array and stop the loop when one is missing.
container.objects = []; // init empty array
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
If you want the first item object1 to be in the [1] spot instead of the more typical [0] spot in the array, then you need to put an empty object into the array's zeroth slot to start with since your example doesn't have an object0 item.
container.objects = [{}]; // init array with first item empty as an empty object
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
An alternate way to do this is by using keys.
var unsorted = objectwithobjects;
var keys = Object.keys(unsorted);
var items = [];
for (var j=0; j < keys.length; j++) {
items[j] = unsorted[keys[j]];
}
You can add an if-statement to check if a key contains 'object' and only add an element to your entry in that case (if 'objectwithobjects' contains other keys you don't want).
That is pretty easy:
var c = { objects: [] };
for (var o in container) {
var n = o.match(/^object(\d+)$/);
if (n) c.objects[n[1]] = container[o];
}
Now c is your new container object, where c.object[1] == container.object1