I'm learning actionscript 3 and trying to get values from the array to be passed one after another into "gift_id": , and basically reward gifts. I am not totally sure if it could be done like this or the best way to achieve it. Any advice would be appreciated.
public function userGift(): Object {
var gift_id: Array = [2373, 9383, 4444, 4557, 8737];
return {
"change_type": "accepted",
"gift_id": ,
};
}
Function can only return single object, so I don't think this is a good way to do it. If you want to reuse it, you can call it multiple times if you pass id as a parameter.
var giftsArray:Array = [];
for each(var id:int in gift_id) {
giftsArray.push( userGift(id) );
}
//You should have an Array full of gift objects.
trace(giftsArray.length);
public function userGift(id:int):Object {
return {
"change_type": "accepted",
"gift_id": id,
};
}
Related
I have two differents arrays with those models
export interface ProfileMaterialCategory{
id?: string
materialCategory_Name?: string
materialCategory_Id: string
quantity: string
profileId?: string
}
And
import { Category } from "./material-asset-model";
export interface UserAssetsCount {
category: Category
userAssetsCount: number;
}
In my .ts file I'm trying to create a method for getting a combined records for all matching materialCategory_Id / category.Id.
The returned array must have this syntax
[category.name:string, userAssetsCount:string, quantity:string]
I tried with filter and includes but it his not working, or I don't take the problem correctly.
This is the arguments that the method takes.
GetMatch(profileAssets: ProfileMaterialCategory[], userAssets: UserAssetsCount[]): Object[] {
var filteredArray = userAssetsAllowed.filter(
as
setAllowed => userAssetsCount.some(
assetCount => assetCount.category.id.toString() == assetAllowed.materialCategory_Id)
return filteredArray
}
When I filter, I receive an element of the array when the condition is true, but it's an element from one of the array, I can't take value from the other.
So, I've succed in one way to do what I needed.
First I created a new DTO model:
export interface UserAssetMatch {
category: Category,
allowed: string,
owned: number
}
Then I make a foreach() loop on one array, and use a filter() on the second array. I keep the matching elements in an intermediate array.
If there is something in the intermediate array, I push the informations that I need in the DTO.
GetMatch(userAssetsAllowed: ProfileMaterialCategory[], userAssetsCount: UserAssetsCount[]): UserAssetMatch[] {
var matchArray: UserAssetMatch[] = [];
userAssetsCount.forEach(userAsset => {
var profileAssets = userAssetsAllowed.filter(userAssetAllowed => userAsset.category.id.toString() == userAssetAllowed.materialCategory_Id);
if (profileAssets.length > 0) {
matchArray.push({
category: userAsset.category,
owned: userAsset.userAssetsCount,
allowed: profileAssets[0].quantity
})
}
});
return matchArray;
I don't think it is a good way to do, but it works. If someone have a better/faster/cleaner way to do, please tell me :)
Hello I have array of friends this.venner
also I have array called this.convensations and output is like this.venner,
but id here is called partner_id (partner_id output is 54312, 54345, 54346 )
now I want compare if this.convensation partner_id and this.venner id if is same
something like this:
if (this.convensation in this.venner) {
//do something
} else {
// do something
}
You can use the Array.prototype.some() method.
If you wrap that in it's own checkExistsInArray function...
function checkExistsInArray(arr, compareObj){
return arr.some(function(obj){
return compareObj[Object.keys(compareObj)] === obj[Object.keys(compareObj)];
});
}
... then you should be able to use that for both arrays by passing in a custom compare object.
var friendExists = checkExistsInArray(this.venner, { id: this.friend });
var conversationExists = checkExistsInArray(this.conversations, { partner_id: this.friend });
Side Note : As others have pointed out, there are libraries out there to readily do this sort of thing. Two of the main players I'm aware of are Underscore.js and Lodash. Even if you choose not to use them, it can sometimes be helpful to see how they work under the hood when looking for a little bit of inspiration.
You can use filter,
var result = this.venner.filter(t=>t.id === '54312');
if (result.length >0) {
//do something
} else {
// do something
}
Simply you can solve this using Undescore.js _.find function
if (.find(this.friend, {"id":this.venner) {
//do something
} else {
// do something
}
I have an array of players, each player is an object that has a number of properties, one is "goals".
var players = [
{
"id":"4634",
"name":"A. Turan",
"number":"0",
"age":"28",
"position":"M",
"goals":"1"
},
{
"id":"155410",
"name":"H. Çalhano?lu",
"number":"0",
"age":"21",
"position":"A",
"goals":"0"
},
{
"id":"4788",
"name":"B. Y?lmaz",
"number":"0",
"age":"30",
"position":"A",
"goals":"2",
}
]
I've written a function to cycle through the array and push every element that has more than '0' goals to an array, topScorers. Like so:
$scope.topScorerSearch = function() {
var topScorers = [];
$scope.teamDetails.squad.forEach(function(o) {
if (o.goals > 0) {
topScorers.push(o)
}
});
return topScorers;
}
With the function called as {{topScorerSearch()}}.
This returns only players who have scored. Perfect.
However, I want to run this on other properties, which will result in a lot of repetitious code. How can I make this a general purpose function that can be executed on different properties?
I tried including the 'prop' parameter, but it didn't work:
$scope.topScorerSearch = function(prop) {
var topScorers = [];
$scope.teamDetails.squad.forEach(function(o) {
if (o.prop > 0) {
topScorers.push(o)
}
});
return topScorers;
}
...and called the function like this:
{{topScorerSearch(goals)}}
Why doesn't this work? Where am I going wrong?
I believe the issue is that prop will not resolve to goals because goals is being treated as a variable with a null or undefined value, making prop null or undefined.
If you use the alternative way of accessing object properties object["property"] and use the function {{topScorers("goals")}} it should work out.
I need help with array asynchronous iterate functionality. I working with node-opcua library in nodejs. There is function session.browse(nodeId, result)
Right now code looks like:
NodesTree = {
"NodesTree":{
"name":"SYM:",
"subf":[]
}
};
the_session.browse("ns=1;s=SYM:", function(err, browse_result){
if(!err) {
var buf = [];
browse_result[0].references.forEach(function(reference) {
if (reference1.browseName.namespaceIndex > 1) {
buf.push(reference);
}
});
NodesTree.subf = buf;
}
});
In result I get references of SYM: folder example:
[{"referenceTypeId":"ns=0;i=35","isForward":true,"nodeId":"ns=6;s=S71500ET200MP station_1","browseName":{"namespaceIndex":6,"name":"S71500ET200MP station_1"},"displayName":{"text":"S71500ET200MP station_1","locale":"en"},"nodeClass":"Object","typeDefinition":"ns=0;i=61"}]
I have Nodes structure in opc like this:
->SYM:
-->PLC
--->PLC_name
---->global_tag <variable>
---->global_tag1 <variable>
---->block
------>blok_tag1 <variable>
------>block_tag2 <variable>
Task is make one complete JSON object as tree for further use.
Logic is that: for each element in the references array get nodeId value and browse for references of the element and assign as element.subf = reference.
Final result something like:
NodesTree = {
"NodesTree":{
"name":"SYM:",
"subf":[
{attributes of PCL structure got by **browse**() + subf:[{ attributes of PLC_name by browse(), subf:
[{....and here again attributes and subf] }, {if no subf just assign subf; [] }]
]
}
};
So need call session.browse() for each reference and all finally bind to one object.
I tried to use Async library each and map in series functions to solve all that, but get nothing wise in result. May be there some smart solution can be found by Stack overflow community. Please help.
I am not familiar with node-opcua but assume that session.browse() is also async. Then something like this might work?
var async = require('async');
async.map(buf,
function(reference, callback) {
session.browse(reference.nodeId, function (err, result) {
callback(err, result);
});
}, function(err, results) {
// results is now an array of all single results
NodesTree.subf = results;
});
I can successfully do this:
App.SomeCollection = Backbone.Collection.extend({
comparator: function( collection ){
return( collection.get( 'lastName' ) );
}
});
Which is nice if I want to have a collection that is only sorted by 'lastName'. But I need to have this sorting done dynamically. Sometimes, I'll need to sort by, say, 'firstName' instead.
My utter failures include:
I tried passing an extra variable specifying the variable to sort() on. That did not work. I also tried sortBy(), which did not work either. I tried passing my own function to sort(), but this did not work either. Passing a user-defined function to sortBy() only to have the result not have an each method, defeating the point of having a newly sorted backbone collection.
Can someone provide a practical example of sorting by a variable that is not hard coded into the comparator function? Or any hack you have that works? If not, a working sortBy() call?
Interesting question. I would try a variant on the strategy pattern here. You could create a hash of sorting functions, then set comparator based on the selected member of the hash:
App.SomeCollection = Backbone.Collection.extend({
comparator: strategies[selectedStrategy],
strategies: {
firstName: function () { /* first name sorting implementation here */ },
lastName: function () { /* last name sorting implementation here */ },
},
selectedStrategy: "firstName"
});
Then you could change your sorting strategy on the fly by updating the value of the selectedStrategy property.
EDIT: I realized after I went to bed :) that this wouldn't quite work as I wrote it above, because we're passing an object literal to Collection.extend. The comparator property will be evaluated once, when the object is created, so it won't change on the fly unless forced to do so. There is probably a cleaner way to do this, but this demonstrates switching the comparator functions on the fly:
var SomeCollection = Backbone.Collection.extend({
comparator: function (property) {
return selectedStrategy.apply(myModel.get(property));
},
strategies: {
firstName: function (person) { return person.get("firstName"); },
lastName: function (person) { return person.get("lastName"); },
},
changeSort: function (sortProperty) {
this.comparator = this.strategies[sortProperty];
},
initialize: function () {
this.changeSort("lastName");
console.log(this.comparator);
this.changeSort("firstName");
console.log(this.comparator);
}
});
var myCollection = new SomeCollection;
Here's a jsFiddle that demonstrates this.
The root of all of your problems, I think, is that properties on JavaScript object literals are evaluated immediately when the object is created, so you have to overwrite the property if you want to change it. If you try to write some kind of switching into the property itself it'll get set to an initial value and stay there.
Here's a good blog post that discusses this in a slightly different context.
Change to comparator function by assigning a new function to it and call sort.
// Following example above do in the view:
// Assign new comparator
this.collection.comparator = function( model ) {
return model.get( 'lastname' );
}
// Resort collection
this.collection.sort();
// Sort differently
this.collection.comparator = function( model ) {
return model.get( 'age' );
}
this.collection.sort();
So, this was my solution that actually worked.
App.Collection = Backbone.Collection.extend({
model:App.Model,
initialize: function(){
this.sortVar = 'firstName';
},
comparator: function( collection ){
var that = this;
return( collection.get( that.sortVar ) );
}
});
Then in the view, I have to M-I-C-K-E-Y M-O-U-S-E it like this:
this.collections.sortVar = 'lastVar'
this.collections.sort( this.comparator ).each( function(){
// All the stuff I want to do with the sorted collection...
});
Since Josh Earl was the only one to even attempt a solution and he did lead me in the right direction, I accept his answer. Thanks Josh :)
This is an old question but I recently had a similar need (sort a collection based on criteria to be supplied by a user click event) and thought I'd share my solution for others tackling this issue. Requires no hardcoded model.get('attribute').
I basically used Dave Newton's approach to extending native JavaScript arrays, and tailored it to Backbone:
MyCollection = Backbone.Collection.extend({
// Custom sorting function.
sortCollection : function(criteria) {
// Set your comparator function, pass the criteria.
this.comparator = this.criteriaComparator(criteria);
this.sort();
},
criteriaComparator : function(criteria, overloadParam) {
return function(a, b) {
var aSortVal = a.get(criteria);
var bSortVal = b.get(criteria);
// Whatever your sorting criteria.
if (aSortVal < bSortVal) {
return -1;
}
if (aSortVal > bSortVal) {
return 1;
}
else {
return 0;
}
};
}
});
Note the "overloadParam". Per the documentation, Backbone uses Underscore's "sortBy" if your comparator function has a single param, and a native JS-style sort if it has two params. We need the latter, hence the "overloadParam".
Looking at the source code, it seems there's a simple way to do it, setting comparator to string instead of function. This works, given Backbone.Collection mycollection:
mycollection.comparator = key;
mycollection.sort();
This is what I ended up doing for the app I'm currently working on. In my collection I have:
comparator: function(model) {
var methodName = applicationStateModel.get("comparatorMethod"),
method = this[methodName];
if (typeof(method === "function")) {
return method.call(null, model);
}
}
Now I can add few different methods to my collection: fooSort(), barSort(), and bazSort().
I want fooSort to be the default so I set that in my state model like so:
var ApplicationState = Backbone.Model.extend({
defaults: {
comparatorMethod: "fooSort"
}
});
Now all I have to do is write a function in my view that updates the value of "comparatorMethod" depending upon what the user clicks. I set the collection to listen to those changes and do sort(), and I set the view to listen for sort events and do render().
BAZINGA!!!!