I have an arrayCollection which I created dynamically like one at bottom:
arrCol = ({"ID":ids[i][0], "Price":ids[i][1], "OtherInfo":ids[i][2]});
I want to group data and summarise Price by ID.
If this ArrayCollection was a SQL table, I could use a query like this:
SELECT ID, SUM(Price), OtherInfo
FROM TableA
GROUP BY ID
So how can I set an AS3 function like the query example in SQL or is there any native ArrayCollection class for this?
Try this, there is no built in function available for your need(sum,groupby) so we need to do manually below code will help you.
var arrCol:ArrayCollection = new ArrayCollection();
arrCol.addItem({"ID":1, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":1, "Price":700, "OtherInfo":"info"});
arrCol.addItem({"ID":2, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":2, "Price":200, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":100, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":400, "OtherInfo":"info"});
arrCol.addItem({"ID":3, "Price":100, "OtherInfo":"info"});
var dic:Dictionary = new Dictionary();
for each (var item:Object in arrCol)
{
if(!dic[item.ID]){
dic[item.ID] = item;
}
else{
var oldSumObj:Object = dic[item.ID];
oldSumObj.Price +=item.Price;
dic[item.ID] = oldSumObj;
}
}
var groupedList:ArrayCollection = new ArrayCollection();
for each (var itemObj:Object in dic)
{
groupedList.addItem(itemObj);
}
output will be:
"groupedList" mx.collections.ArrayCollection (#27af939)
[0] Object (#8836569)
ID 1
OtherInfo "info"
Price 800 [0x320]
[1] Object (#87a7c71)
ID 2
OtherInfo "info"
Price 300 [0x12c]
[2] Object (#87a7bc9)
ID 3
OtherInfo "info"
Price 600 [0x258]
While you can't make SQL type queries in AS3, you can use its bevy of methods to achieve the same result.
// Work with an array. Child elements must be an associative array (structure/object/hash-table)
var ac:Array = [
{"name":"apple", "price":100, "color":"red"},
{"name":"banana", "price":50, "color":"yellow"},
{"name":"pear", "price":250, "color":"green"},
]
// Apply the order your want based on the property you're concerned with.
ac.sortOn("price", Array.ASCENDING)
// If necessary, create a subset of that array with the "select"-ed columns.
var output:Array = [];
for each (var entry:Object in ac) {
output.push({entry.name, entry.color});
}
// Printing output will result in
// 0:{"name":"banana", "color":"yellow"},
// 1:{"name":"apple", "color":"red"},
// 2:{"name":"pear", "color":"green"}
Related
Trying to convert a json string to key value pairs using Newtonsoft but no luck so far.
Response from the API:
var response = #"{'result':{'0199 - B344EE33':
{
'6400_00260100':{'1':[{'val':336688}]},
'6400_00462500':{'1':[{'val':null}]},
'6800_00832A00':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_008AA200':{'1':[{'low':0,'high':null,'val':0}]}
}}}";
Result I want is a new object of key value pairs:
{
"6400_00260100" : 336688,
"6400_00462500" : null,
"6800_00832A00" : 3000,
"6800_008AA200" : 0
}
In the response the result will always be the first and only prop. In the next level the code 0199 - B344EE33 can change but there will be only one prop in this level so we can always take the first one. Then in the last level we always need the val property.
What I have is the following but for getting the key value pairs in a clean way I got stuck:
var json = JObject.Parse(response);
var result = json["result"].First;
var path = result.Path;
UPDATE
var jObjectResult = new JObject();
var response = #"{'result':{'0199 - B344EE33':
{
'6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
'6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
'6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_08822B00':{'1':[{'val':'SMA'}]},
'6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
}}}";
var json = JObject.Parse(response);
var json_serial = json["result"].First.Children<JObject>().ToList()[0];
foreach(var token in json_serial)
{
var tokenKey = token.Key;
var tokenVal = token.Value.SelectToken("$.1[0].val");
jObjectResult.Add(tokenKey, tokenVal);
}
You could use SelectTokens with the recursive descent operator .. to find all the val properties, then walk up the chain using .Parent repeatedly to get the corresponding key. Create new JProperties from this information and put them into a new JObject to get your result. Here is a "one-liner":
var result = new JObject(
JObject.Parse(response)
.SelectTokens("$..val")
.Select(jt => new JProperty(
((JProperty)jt.Parent.Parent.Parent.Parent.Parent.Parent).Name,
jt
))
);
Fiddle: https://dotnetfiddle.net/TbZ7LS
At the end with some pointers form #Brian Rogers I came with the following solution:
// Arrange
var response = #"{'result':{'0199 - B344EE33':
{
'6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
'6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
'6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
'6800_08822B00':{'1':[{'val':'SMA'}]},
'6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
}}}";
// Act
var json = JObject.Parse(response);
var json_serial = (JProperty)json["result"].First();
var jObjectResult = new JObject(
json_serial.Value.Select(p =>
{
return new JProperty(
((JProperty)p).Name,
p.First.SelectToken("$.1[0].val")
);
}));
I m fetching data from mysql database in nodejs/expressjs and want to create nested json from it.
I want to create Json object like this :
[
{id : 1,countryName:'USA',population:10000,
cities : [
{id:1,cityName:'NY',countryId:1},{id:2,cityName:'Chicago',countryId:1}
]
},
{id : 2,countryName:'Canada',population:20000,
cities : [
{id:1,cityName:'Toronto',countryId:2},{id:2,cityName:'Ottawa',countryId:2}
]
}
]
here is my code in expressJs but it is giving me an empty array of JSON
app.get("/checkJson",function(req,res){
var country = {};
var outerobj = {};
var outerArray = [];
conn.query("select * from country",function(err,result){
for(var i = 0 ;i<result.length;i++){
var cityobj = {};
var city = [];
conn.query("select * from city where countryId ="+result[i].id,function(err,cityResult){
for(var j = 0;j<cityResult.length;j++){
cityobj = {cityName:cityResult[j].name,countryId:cityResult[j].countryId};
city.push(cityobj);
} //end city forloop
}) //end city Query
outerobj = {id:result[i].id,countryName:result[i].name,pop:result[i].population,cities:city};
outerArray.push(outerobj);
} //end country forloop
}) // end country query
console.log(outerArray);
})
MySQL returns flat objects. We want to nest joined objects.
Let's say we have courses table, each course belongs to a department and has various course sections. We would like to have a resulting courses array that has a department object property within it and have a list of course sections.
This is a good solution from kyleladd on github
https://github.com/ravendano014/node-mysql-nesting
Im trying to get property from oData return model. I set data in success callback function from oData to JSON model.
oODataModel.read("/ConnObjSet?$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'",
true,
true,
false,
function _OnSuccess(oData, oResponse){
var oJSON = new sap.ui.model.json.JSONModel();
oJSON.setData(oData);
sap.ui.getCore().setModel(oJSON, "ConnectionObject");
},
This is my JSON object in console log and highlighted property I want to get. I want to get every 15 Buspartner number from whole array.
And this is what I tried to get property:
var oLog = sap.ui.getCore().getModel("ConnectionObject").oData.results;
console.log(oLog);
If you have an array of objects, you can get an array of properties from each of these objects by using the Array.map() function.
So in your case:
var aResults = this.getView().getModel().getProperty("/results");
var aBuspartner = aResults.map(function (r) { return r.Buspartner});
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray", aBuspartner)
Please try:
var aResults = this.getView().getModel().getProperty("/results");
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setProperty("/resultarray",new Array())
for(var i = 0; i<aResults.lenght;i++){
oJSONModel.getProperty("/resultarray").push(aResults[i].Buspartner)
}
You could also try to add a filter and select to your oData.read
The oData-URL
http://services.odata.org/V2/Northwind/Northwind.svc/Products
selects all Product with all their properties
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$filter=UnitsInStock%20eq%2017
shows only Products with "UnitsInStock=17"
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$select=ProductID&$filter=UnitsInStock%20eq%2017
selects only the ProductID of Products with "UnitsInStock=17"
so
oODataModel.read("/ConnObjSet?$select=Buspartner&$filter=Objecttype eq 'CONNOBJ' and ConnObject eq '20000000002'"
...
should get the filtered Buspartners directly.
I am fetching data from the indexed database in HTML 5, I am able to successfully get the values but I want it to bind it to some data-grid view of ASP.NET
The code which I am using to get the values from the indexed database is
if(currentDatabase) {
var objectStore = currentDatabase.transaction([objStore]).objectStore(objStore);
var traveller = [];
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
var v = cursor.value;
traveller.push("id ="+v.id);
traveller.push("Name ="+v.traveler);
traveller.push("Destination ="+v.destination);
traveller.push("Transportation ="+v.transportation);
cursor.continue();
}
this allows me to store the data in the array, how can I bind it to datagrid view,
I just noticed that you put all objects into the same array without hierarchy, and this will result in array that is long number of properties multiplied by number of records
Instead what you should do is create an array for each object and then push that array into the main array.
var traveller = [];
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
var v = cursor.value;
var obj = {};
obj.push("id ="+v.id);
obj.push("Name ="+v.traveler);
obj.push("Destination ="+v.destination);
obj.push("Transportation ="+v.transportation);
traveller.push(obj);
cursor.continue();
}
}
I posted my problem a few hours ago, but I think I figured out how to ask my question in a more comprehensible way.
This is my code:
// 1. Intro
var introPL1:Array = ["intro1","intro2","intro3","intro4"];
var introPL2:Array = ["intro5","intro6","intro7","intro8","intro9"];
var introPL3:Array = ["intro10","intro11"];
var introPL4:Array = ["intro12","intro13"];
var allIntro:Array = [introPL1,introPL2,introPL3,introPL4];
// 2. Clothes
var clothesPL1:Array = ["clothes1","clothes2","clothes3","clothes4","clothes5"];
var clothesPL2:Array = ["clothes6","clothes7","clothes8"];
var clothesPL3:Array = ["clothes9","clothes10"];
var clothesPL4:Array = ["clothes11","clothes12","clothes13"];
var allClothes:Array = [clothesPL1,clothesPL2,clothesPL3,clothesPL4];
// 3. Colored Numbers
var colNumPL1:Array = ["colNum1","colNum2","colNum3","colNum4","colNum5"];
var colNumPL2:Array = ["colNum6","colNum7","colNum8"];
var colNumPL3:Array = ["colNum9","colNum10"];
var colNumPL4:Array = ["colNum11","colNum12","colNum13"];
var allColNum:Array = [colNumPL1,colNumPL2,colNumPL3,colNumPL4];
var allStuff:Array;
allStuff = allIntro.concat(allClothes, allColNum);
trace(allStuff[4]);
When I trace allStuff[4] it displays "clothes1,clothes2,clothes3,clothes4,clothes5".
The thing is, I would like all the stuff to be in the allStuff array (without sub-arrays) and when I trace allStuff[4], I would like it to display "intro5" (the fifth item in the huge allStuff array).
the function you want to use then is concat
here's the example from adobe
var numbers:Array = new Array(1, 2, 3);
var letters:Array = new Array("a", "b", "c");
var numbersAndLetters:Array = numbers.concat(letters);
var lettersAndNumbers:Array = letters.concat(numbers);
trace(numbers); // 1,2,3
trace(letters); // a,b,c
trace(numbersAndLetters); // 1,2,3,a,b,c
trace(lettersAndNumbers); // a,b,c,1,2,3
it's pretty straight forward:
allStuff= allStuff.concat(introPL1,introPL2,introPL3,introPL4,clothesPL1,clothesPL2,clothesPL3,clothesPL4,colNumPL1,colNumPL2,colNumPL3,colNumPL4);
you could also do a
allStuff = []
for each(var $string:String in $arr){
allStuff.push($string)
}
for each array, or make it into a function
Okay, once you have declared your arrays like so, you need an additional operation to flatten your arrays allClothes and so on. Do like this:
function flatten(a:Array):Array {
// returns an array that contains all the elements
// of parameter as a single array
var b:Array=[];
for (var i:int=0;i<a.length;i++) {
if (a[i] is Array) b=b.concat(flatten(a[i]));
else b.push(a[i]);
}
return b;
}
What does it do: The function makes an empty array first, then checks the parameter member by member, if the i'th member is an Array, it calls itself with that member as a parameter, and adds the result to its temporary array, otherwise it's just pushing next member of a into the temporary array. So, to make your allIntro a flat array, you call allIntro=flatten(allIntro) after declaring it as you did. The same for other arrays.