javascript get second variable from array - javascript

I have javascript that is checking multiple fields in Dynamics CRM. If some of them or all are "1" it will use the highest value to use in a calculation.
I pasted a part of the script:
var level1 = {
percentage: 0,
label: "MyLabel"
}
var level2 = {
percentage: 0,
label: "MySecondLabel"
}
if (Xrm.Page.getAttribute("conditioninterested").getValue() == 1) {
level1[0] = 50;
}
if (Xrm.Page.getAttribute("revenueconditionquote").getValue() == 1) {
level2[0] = 70;
}
var chance = Math.max(level1[0],level2[0]);
How do I get the corresponding label after the Math.max found out the percentage to use?

With the way your data is structured I would add the level objects to an array and then filter by chance. filter returns an array so you need to take the first element [0] which is an object, and then the label value from that object.
var label = [level1, level2].filter(function (el) {
return el[0] === chance;
})[0].label; // MySecondLabel
DEMO

First of all, you are could have made a constructor function to declare the object instances, secondly level1 and level2 are objects, So basically there are two ways you can access object properties:
Dot notation, eg. level1.lebel or level1.percentage
the [] notation. You need to put the key in, not the index number. Objects don't have indexes, they are key and value pairs. and also they are un-ordered.

Related

Named objects and collection of them

not sure how to ask tbh :)
I'm used of PHP's associative arrays so much that I struggle to understand how to create an "named array" of objects.
Example:
I have two arrays, two ints and one boolean. This represents one of my entities. I have multiple entities on which I'm doing some work.
In PHP I would write:
$entitites[$entitity_id]['items'][] = $item;
$entitites[$entitity_id]['items_status'][] = $item_status;
$entitites[$entitity_id]['items_count']++;
and so on..
How do I do this with objects in JS?
var entities = {items:[], items_status: [], items_count: 0};
entities[entity_id].items.push(item)
How does one name his object for later access (via name or in my case, entity_id?)
This code doesnt work for me to this extend that my webpage goes blank without any errors produced :S
I also tried this:
var entities = {};
var entity = {items:[], items_status: [], items_count: 0};
but then I dont know how to always add values to already existing object in entities object and how to call that exact object via name eg. entity_id.
Halp :(
Keep entities as an object. Then you can just go ahead and add each entity_id as a key and an object which has all the details of that entity as the value.
var entities = {};
entities["1234"] = {
"items" : [],
"items_status" : [],
"items_count" : 0
};
There are 2 types involved here: Objects & Arrays.
Arrays are simple and you're probably familiar with them from any other language:
var myArray = []; // this is an empty array
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
// you could also use "var myArray = [1, 2, 3];" instead
alert(myArray[1]); // alerts the value 2
Note: arrays are actually objects, and can have non-index properties as well
You can also use various array functions such as .push(), .pop(), .shift() and so on to mutate the array instead.
Objects share the square brackets notation, but the purpose is different:
var myObject = {}; // this is an empty object
myObject[0] = 1;
myObject[1] = 2;
myObject[2] = 3;
alert(myObject[1]); // alerts the value 2
// but also...
myObject['prop'] = 4;
alert(myObject['prop']); // alerts the value 4
// and
myObject.prop2 = 5;
alert(myObject.prop2); // alerts the value 5
// and lastly
alert(myObject.prop); // alerts the value 4
So while arrays are accessed by index, objects are accessed by property names.
As for your entities, it looks like an array of objects. Lets see how we can do that:
function Entity() {
this.items = [];
this.items_status = [];
this.items_count = 0;
}
var entitites = [];
entities.push(new Entity());
entities[0].items = [1, 2, 3];
entities[0].items_status = ['good', 'good', 'poor'];
entities[0].items_count = 3;
Or you can wrap insertion in a more elegant function:
Entity.prototype.insert(item, status) {
this.items.push(item);
this.items_status.push(status);
this.items_count++;
}
entities[0].insert(4, 'excellent!');
If you want to keep control of the indexes in your JS array you can do so by not using .push() :
var entities = [];
entities[5] = {items:[], items_status:[], items_count:0};
Just replace 5 by your integer entity_id variable, and there you go.
You can use a regular javascript object to create the associative array you're looking for.
Actually it's PHP's implementation that's abit off but all they do is call it different (associative array) to most other language that simply refer to it as an object or hash.
You can use numeric keys in JS and still access them with the [] square brackets.
It works like this:
var my_obj = {};
my_obj[5] = 'any value';
console.log(my_obj); // {5: 'any value'}
JS will not add any redundant undefined to missing indexes either so when looping over the collection you won't loop over undefined.
Also, I can access the object by using the key as a string or as number so you won't have to check if the key is the right type. Taken from the above example:
console.log(my_obj['5']); // 'any value'
console.log(my_obj[5]); // 'any value'
JS Objects are the equivelant of PHP assoc arrays except JS objects are much more flexible than PHP's associative arrays.
The only downside to this is that you can't have duplicate keys.
No two keys may exist that share the same name, in an array if you .push(an_item) it will create a new index making even a duplicate data entry unique but when overwriting a key with a new value only the last value will persist, mind that :)

array.sort not working on array of objects

I got the following object array:
var arr = [{
2: {
1: { name: "test" },
2: { name: "apple" }
},
3: {
1: { name: "banana" },
2: { name: "pear" }
}
}];
Just some sample data. Now, I got 3 textareas:
<textarea id="first"></textarea>
<textarea id="second"></textarea>
<textarea id="third"></textarea>
And I have the following custom-made function:
function sort(alt)
{
arr.sort(function (a,b)
{
console.log(a);
if (a[2].name < a[2].name)
return (alt) ? 1 : -1;
if (a[2].name > a[2].name)
return (alt) ? -1 : 1;
return 0;
});
}
It should sort the array of objects by name, ascending or descending according to parameter. Now, I got 2 problems. This way I append all the values to the textareas:
for (var key in arr[0])
{
var obj = arr[0][key];
$(ID).append(obj[2].name + '\n');
}
The first time, that code will be executed without running sort. The second time, sort will be executed with false as parameter, than that code will be executed. The third time sort will be executed with true as parameter, than that code will be executed. However, the output of all textboxes is exactly the same.
This is a link to the jsfiddle:
http://jsfiddle.net/JoshB1997/gow4vzsc/
Also, the console.log(a) doesn't get printed in the console.
So variable arr is an array but as far as I can see it contains only one object.
You're trying to sort directly onto the array, since it only has one object it will simply never sort because there is nothing to sort.
You'll want to access arr[0] which is the object containing the actual objects you want to sort however the Object prototype doesn't contain any of the array functions so you cannot call sort on it even tho technically an Array is an Object an Array inherits from Object and not the other way around so the methods from Object are available to Array but not the other way around.
Also, you're trying to compare the same a[2].name with itself so it'll always be false since it's equal, not > or <.
In your case I extract all the name properties from every nested object you have like this (considering the usage of the original arr):
var compare = [];
var alt = false;
for (k in arr[0]) {
if (arr[0].hasOwnProperty(k)) {
for (l in arr[0][k])
if (arr[0][k].hasOwnProperty(l))
compare.push(arr[0][k][l].name);
compare.sort(function(a, b) {
if (a == b)
return 0;
else if (a < b)
return alt ? 1 : -1
else
return alt ? -1 : 1
});
Now you can use the compare array to output the sorted names correctly.
Also - your construction seems overly complex? It has objects and within them are nested objects but you're only sorting and displaying names, is there any reason this structure has to be maintained?
If not I would highly recommend you simplify this to just be an array of names, the loop I made above is far from beautiful and I'd rather have you not use it since it assumes that the outmost object is an object filled with other objects that all have the name property. This code could still break without an extra arr[0][k][l].hasOwnProperty('name').
Either way, the compare array simply contains all the names and it easily sortable with the default sort if you don't make things to complex for yourself.
I suggest you to use http://underscorejs.org/ that contains quite really useful function to transform from object to arrays.
For example in this case you can use something like http://underscorejs.org/#values
let values = _.values(arr[0]);
Now values is an array that contains your two object (2,3) in the form
values = [
{
1: {
name: "test"
},
2: {
name: "apple"
}
},
{
1: {
name: "banana"
},
2: {
name: "pear"
}
}
]
and here you can call your sort function
There is my demo on your code with underscore.js http://jsfiddle.net/gow4vzsc/3/
EDIT: If you cant/wont to include an entire library you can write your code for get the values:
values = [];
for(key in arr[0]){
values.push(arr[0][key]);
}
Here a demo without underscore.js http://jsfiddle.net/3L7ttu2r/1/

Getting Length of Object in Javascript / jQuery

I am trying to set up an array in jQuery and I then need to do a for loop on it. But it seems that I cant use an associative array for some reason?
var items = new Array();
items['foo'] = 123456;
items['bar'] = 789012;
items['baz'] = 345678;
items['bat'] = 901234;
alert(items.length);
This is just a test, but it return 0?
You can't make associative array in JavaScript like what you want, instead you can use Object.
For example:
var items = {
foo : 123456,
bar : 789012,
baz : 345678,
bat : 901234
}
And to calculate the length you can do:
var getObjectSize = function(obj) {
var len = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) len++;
}
return len;
};
Use: getObjectSize(items); // output: 4
For more see here.
Another one is:
Object.keys(items).length;
But not supported by all browsers.
var items = new Array();
items['foo'] = 123456;
The problem lies in the very first line. You believe that you are adding an item to the array at the index foo, but you are actually adding a property to the items variable with a key foo and value 123456. If you were to type items.foo it would give you back your 123456.
The problem with this approach is that adding a property to an array does not magically increase it's length.
If you want to have non-numeric indexes, you need to use an object instead of an array:
var items = {
foo: 123456,
bar: 789012,
baz: 345678,
bat: 901234
};
Another approach might be to set up two different arrays, which you construct in parallel:
var items = [], items2 = [];
items.push('foo');
items2.push(123456);
// etc.
alert(items2.length);​
The efficiency of this approach depends on how you'll use it. If you're only going to loop through the list of items and do something to each of them, this approach may be more efficient. But if you need to use it like an associative array (items['foo']), then you're better off building an object.
The .length property returns the highest numerical index of the array. Thus, in your case, there is no numerical index and it returns 0. Try
items[98] = "something";
items.length will be 98..! Use the .length property with caution, and if you also want to count the non-numerical indici, loop over the Object (an Array is also an Object) and count its ownProperties.

Extracting multiple object values

I have an object like this:
object["key1"] = "text1"
object["key2"] = "text2"
object["key3"] = "text1"
object["key4"] = "text3"
How can I give out (e.g. alert) the elements with the same values (text1, text2 and so on)?
In the above example it should be object["key1"] and object["key2"].
Thanks
You could "invert" your object (properties become values, values become properties):
var byValue = {};
for (var prop in object) {
if (!(object[prop] in byValue)) {
byValue[object[prop]] = [];
}
byValue[object[prop]].push(prop);
}
This should yield this structure:
{
'text1': ['key1', 'key3'],
'text2': ['key2'],
'text3': ['key4']
}
Then, you can detect those values that had duplicate keys:
for (var value in byValue) {
if (byValue[value].length > 1) {
alert(byValue[value].join(', '));
}
}
I have sorted the array and then considered that you would want to alert,or do any
functionality, only once for every repeated element.
WARNING: Sorting can get heavy with the size of the array
http://jsfiddle.net/SPQJ7/
The above fiddle is already setup and working with multiple reapeated elements
I updated my script
http://jsfiddle.net/HerrSerker/LAnRt/
This does not check for identity in complex values, just for equality (see foo example)

In Javascript how to compare and store the values dynamically like Key and value object

In javascript arrays i need to check and assign the values in array like key and value pair .
For example :
if i added some values in the array and the second time the same value is retrieving one more time at that time i need to compare my array and i need to increment the previous value instead of storing the value in the array.please suggest me how to achieve this through javascript or jQuery
In sounds like you want something like a hash table. In JavaScript you should use objects for this:
var data = {};
data['key'] = 5;
// later
data['key'] += 10; // data['key'] is now 15
More information about objects in MDC - Working with Objects.
If you want to associate data with an HTML element, then have a look at jQuery's .data() [docs] method (which uses objects too, so in any case you have to learn about them ;))
If I get you right, you want to check if a given value already exists in an Array and if so, you want to increment that value by... "one" I guess ?
var foo = [10, 7, 44, 12, 102, 5],
pos = foo.indexOf(44);
if( pos > -1 ) {
foo[pos]++;
}
This way you can encapsulate the function which counts the numbers of occurrences of the values and the object in which the counts are stored:
var count = function() {
var counts = {};
return function(key) { if (typeof counts[key]=="number") counts[key]++; else counts[key]=1; return counts[key]; };
}();
document.write(count("a")); // 1
document.write(count("b")); // 1
document.write(count("a")); // 2

Categories

Resources