I'm probably missing something in the documentation but cannot seem to find it right now.
Let's assume I have a data object like this:
{
value1: number,
value2: number,
computed: number
}
Building an AgGrid that displays a set of these objects as rows with value1/2 being editable while computed is not editable is straightforward.
I can use expressions or functions to create a dynamic column which calculates e.g. value1 * value2. If I change value1 or value2 the dynamic column gets refreshed with the new values.
The question is, is there a way to bind the dynamic column to the computed field, or do I have to subscribe to row changes and do the updating of the computed field manually?
Cheers
Based on this example
function getRowData() {
var rowData = [];
for (var i = 1; i <= 20; i++) {
rowData.push({
group: i < 5 ? "A" : "B",
a: (i * 863) % 100,
b: (i * 811) % 100,
c: (i * 743) % 100,
d: (i * 677) % 100,
e: (i * 619) % 100,
f: (i * 571) % 100,
t:1000 <--- added
});
}
return rowData;
}
and in columnDefs
{
headerName: "Total",
valueGetter: "data.t = (data.a + data.b + data.c + data.d + data.e + data.f)",
editable: false,
aggFunc: "sum",
cellClass: "total-col"
},
{
field: "t", -- just for test
}
So everything handled here
valueGetter: "data.t = (data.a + data.b + data.c + data.d + data.e + data.f)",
DEMO
Related
So I have a List of Maps of two dynamic variables.
[{Title: product 1, Item Score: 87.3, Characters: 72, Image Count: 6},
{Title: product 2, Item Score: 85.1, Characters: 56, Image Count: 2}]
How would I add up all of them item scores? There are more items than this in the full file.
I would look at fold in the standard library https://api.dart.dev/stable/1.10.1/dart-core/List/fold.html.
With fold, you iterate over the list of maps, and the first argument is your starting value. In the case of sum, this would be 0. Your inner function in the fold takes 2 arguments, the current accumlation(sum), and the item in your list that is currently being iterated over.
E.g.:
const itemScores = [{'itemScore': 1}, {'itemScore': 2}, {'itemScore': 44}];
var sum = itemScores.fold(0, (i, el){
return i + el['itemScore'];
});
Where i is the current value of the accumulator, and el is the current item in the list being iterated over.
Assuming that, you need to store the value in some variable, you can simply use List.forEach((element){ })
Advantage, you can iterate over as many data as you can, and then store the value
void main(){
var data = [{"Title": "product 1", "Item Score": 87.3, "Characters": 72, "Image Count": 6}, {"Title": "product 2", "Item Score": 85.1, "Characters": 56, "Image Count": 2}];
double totalScores = 0.0;
// looping over data array
data.forEach((item){
//getting the key direectly from the name of the key
totalScores += item["Item Score"];
});
print(totalScores); // OUTPUT ==> 172.39999999999998
}
List arr = [[1,2,3],[4,5,7],[8,9,10],[14,15,19]];
int stairsIn203(List<List<int>> arr) {
// your code here
int _a = 0 ;
List _b = [];
for(List i in arr){
_b += i;
}
_a = _b.reduce((value, element) => value + element) * 20;
return _a;
}
Or
int stairsIn20(List<List<int>> arr) => arr.expand((e) => e).reduce((v, e) => v + e) * 20;
var sum = [{Title: product 1, Item Score: 87.3, Characters: 72, Image
Count: 6}, {Title: product 2, Item Score: 85.1, Characters: 56, Image
Count: 2}]].reduce((item1, item2) => item1["Item Score"] +item2["Item
Score"]);
In my ag-grid I want to display counts of rows next to each filter choice in a set filter, and maybe sort choices by that count (descending).
This is what it looks like by default:
I want the choices to be displayed as
Select All (88)
Katie Taylor (2)
Darren Sutherland (1)
John Joe Nevin (1)
Barack Obama (0)
...
What is the most efficient way to get those counts (and maybe sort the choices accordingly) from the row data, taking into account filters already set in the other fields (if any)?
Assuming your columns field is "name", you could try building up a map and refer to this in the filters cellRenderer:
var nameValueToCount = {};
function updateNameValueCounts() {
nameValueToCount = {};
gridOptions.api.forEachNodeAfterFilter((node) => {
if(!nameValueToCount.hasOwnProperty(node.data.name)) {
nameValueToCount[node.data.name] = 1;
} else {
nameValueToCount[node.data.name] = nameValueToCount[node.data.name] + 1;
}
});
}
And your column def would look like this:
{
headerName: "Name",
field: "name",
width: 120,
filter: 'set',
filterParams: {
cellRenderer: NameFilterCellRenderer
}
},
And finally, the NameFilterCellRenderer would look like this:
function NameFilterCellRenderer() {
}
NameFilterCellRenderer.prototype.init = function (params) {
this.value = params.value;
this.eGui = document.createElement('span');
this.eGui.appendChild(document.createTextNode(this.value + " (" + nameValueToCount[params.value] + ")"));
};
NameFilterCellRenderer.prototype.getGui = function () {
return this.eGui;
};
You would need to ensure that you called updateCountryCounts to update it when data changed (either with new/updated data, or when a filter was updated etc), but this should work for your usecase I think
I have doc collection which have object type field named price (i.e., see below), I just want to update/insert that field by adding new key value pairs to it.
suppose i have this as collection (in db):
[
{
_id: 1,
price: {
amazon: 102.1,
apple: 500
}
},
....
....
];
Now I want to write an query which either update price's or inserts if not exist in price.
let's suppose these as input data to update/insert with:
var key1 = 'ebay', value1 = 300; // will insert
var key2 = 'amazon', value2 = 100; // will update
assume doc having _id: 1 for now.
Something like $addToSet operator?, Though $addToSet only works for array & i want to work within object).
expected output:
[
{
_id: 1,
price: {
amazon: 100, // updated
apple: 500,
ebay: 300 // inserted
}
},
....
....
];
How can i do/achieve this?
Thanks.
You could construct the update document dynamically to use the dot notation and the $set operator to do the update correctly. Using your example above, you'd want to run the following update operation:
db.collection.update(
{ "_id": 1 },
{
"$set": { "price.ebay": 300, "price.amazon": 100 }
}
)
So, given the data input, you would want to construct an update document like { "price.ebay": 300, "price.amazon": 100 }
With the inputs as you have described
var key1 = 'ebay', value1 = 300; // will insert
var key2 = 'amazon', value2 = 100; // will update
Construct the update object:
var query = { "_id": 1 },
update = {};
update["price."+key1] = value1;
update["price."+key2] = value2;
db.collection.update(query, {"$set": update});
this is my collection structure :
coll{
id:...,
fieldA:{
fieldA1:[
{
...
}
],
fieldA2:[
{
text: "ciao",
},
{
text: "hello",
},
]
}
}
i want to extract all fieldA2 in my collection but if the fieldA2 is in two or more times i want show only one.
i try this
Db.runCommand({distinct:’coll’,key:’fieldA.fieldA2.text’})
but nothing. this return all filedA1 in the collection.
so i try
db.coll.group( {
key: { 'fieldA.fieldA2.text': 1 },
cond: { } },
reduce: function ( curr, result ) { },
initial: { }
} )
but this return an empty array...
How i can do this and see the execution time?? thank u very match...
Since you are running 2.0.4 (I recommend upgrading), you must run this through MR (I think, maybe there is a better way). Something like:
map = function(){
for(i in this.fieldA.fieldA2){
emit(this.fieldA.fieldA2[i].text, 1);
// emit per text value so that this will group unique text values
}
}
reduce = function(values){
// Now lets just do a simple count of how many times that text value was seen
var count = 0;
for (index in values) {
count += values[index];
}
return count;
}
Will then give you a collection of documents whereby _id is the unique text value from fieldA2 and the value field is of the amount of times is appeared i the collection.
Again this is a draft and is not tested.
I think the answer is simpler than a Map/Reduce .. if you just want distinct values plus execution time, the following should work:
var startTime = new Date()
var values = db.coll.distinct('fieldA.fieldA2.text');
var endTime = new Date();
print("Took " + (endTime - startTime) + " ms");
That would result in a values array with a list of distinct fieldA.fieldA2.text values:
[ "ciao", "hello", "yo", "sayonara" ]
And a reported execution time:
Took 2 ms
I run an IRC bot and I have a function which returns 1 random url using Math.random at the moment, from my Mongodb collection.
I would like to refactor it to return x number of unique items, and for each subsequent invocation of the url fetching command .getlinks I would like that it keeps everything unique, so that a user doesn't see the same link unless all the possible links have been already returned.
Is there some algorithm or native mongodb function I could use for this?
Here's a sample scenario:
I have a total of 9 records in the collection. They have a _id and url field.
user a: .getlinks()
bot returns: http://unique-link-1, http://unique-link-2, http://unique-link-3, http://unique-link-4
user a: .getlinks()
bot returns: http://unique-link-5, http://unique-link-6, http://unique-link-7, http://unique-link-8
user a: .getlinks()
bot returns: http://unique-link-9, http://unique-link-6, http://unique-link-1, http://unique-link-3
Background information:
There's a total of about 200 links. I estimate that will grow to around 5000 links by the end of next year.
Currently the only thing I can think of is keeping an array of all returned items, and grabbing all items from the collection at once and getting a random one 4 times and making sure it's unique and hasn't been shown already.
var shown = [], amountToReturn = 4;
function getLinks() {
var items = links.find(), returned = [];
for ( var i = 0; i<amountToReturn; i++ ) {
var rand = randItem( items );
if ( shown.indexOf( rand.url ) == -1 && shown.length < items.length ) ) {
returned.push( rand.url );
}
}
message.say( returned.join(',') );
}
You should find a number of possible options to get random item(s) from Collection here ...
http://jira.mongodb.org/browse/SERVER-533
Another intersting method is documented here ...
http://cookbook.mongodb.org/patterns/random-attribute/
The method mentioned above basically creates a new key/value on the document using Math.random()
> db.docs.drop()
> db.docs.save( { key : 1, ..., random : Math.random() } )
> db.docs.save( { key : 1, ..., random : Math.random() } )
> db.docs.save( { key : 2, ..., random : Math.random() } )
... many more insertions with 'key : 2' ...
> db.docs.save( { key : 2, ..., random : Math.random() } )
...
Get random records form mongodb via map/reduce
// map
function() {
emit(0, {k: this, v: Math.random()})
}
// reduce
function(k, v) {
var a = []
v.forEach(function(x) {
a = a.concat(x.a ? x.a : x)
})
return {a:a.sort(function(a, b) {
return a.v - b.v;
}).slice(0, 3 /*how many records you want*/)};
}
// finalize
function(k, v) {
return v.a.map(function(x) {
return x.k
})
}