How to iterate over dictionary in assemblyscript - assemblyscript

let treasury: Record<string, string> = {};
treasury.firstWallet = "0xEA91B5E687a490380C52d264D5d36558d79F4188".toLowerCase()
for (let wallet in treasury) { ...
With this code I am getting the below, with a little red arrow between 'wallet' and 'in', and a '; expected' under 'wallet'
Compile subgraphERROR TS1110: Type expected.
for (let wallet in treasury) {
So what's wrong with this and what's the proper way to do this?

AssemblyScript doesn't have dynamic objects. But you can use Map
const treasury: Map<string, string> = new Map()
.set("firstWallet", "0xea91b5e687a490380c52d264d5d36558d79f4188")
.set("secondWallet", "0xea91b5e687a490380c52d264d5d36558d79f4188")
const wallets = treasury.values();
for (let i = 0, len = wallets.length; i < len; i++) {
let wallet = wallets[i];
// ...
}

Related

elegant way of capturing a reference to an integer variable?

I have this snippet:
let mut animation_index = 0 as usize;
let mut ptr : *mut usize = &mut animation_index as _;
{
io_context.window().add_key_callback(
Box::new(move |key_states| {
if key_states[KbKey::Space.to_index()] == KeyActionState::Press
{
unsafe {
*ptr += 1;
println!("{}", animation_index);
}
}
})
);
}
Basically it adds a callback such that if and when I press space, the integer variable animation_index goes up by 1. This works, but requires the use of mutable pointers and unsafe, which is very ugly.
I'd like to have the same logic but ideally do it with pure safe rust isntead.
It looks like you are trying to share a mutable value across threads.
Typically, this is done with atomics, Arc<Mutex<T>> or Arc<RwLock<T>>.
use std::synce::{Arc, RwLock};
let mut animation_index = Arc::new(RwLock::new(0usize));
{
// a clone of the counter that can be moved into the callback
let animation_index = animation_index.clone();
io_context.window().add_key_callback(
Box::new(move |key_states| {
if key_states[KbKey::Space.to_index()] == KeyActionState::Press
{
let index = animation_index.write().unwrap();
*index += 1;
println!("{}", index);
}
})
);
}
With atomics it would look something like this:
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
let mut animation_index = Arc::new(AtomicUsize::new(0));
{
// a clone of the counter that can be moved into the callback
let animation_index = animation_index.clone();
io_context.window().add_key_callback(
Box::new(move |key_states| {
if key_states[KbKey::Space.to_index()] == KeyActionState::Press
{
let index = animation_index.fetch_add(1, Ordering::SeqCst);
println!("{}", index);
}
})
);
}

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/

Using variable names as property names in lodash _.findIndex

var ids = ["John", "Mary", "Joe", "Chase", "Sarah"];
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var max = 25; // fixed for simplicity
var maxObj = _.findIndex(people['scores'], { id : max });
}
The above does not work as _.findIndex returns -1 for maxObj. However, if i explicitly define the property name as a string (instead of using the id variable), it works.
var maxObj = _.findIndex(people['scores'], { "John" : max });
Is there a way to pass variable values to the property name in lodash or an alternate way to achieve this using lodash?
You could construct an object literal using the dynamic key and then feed that to _.findIndex:
var ids = ["John", "Mary", "Joe", "Chase", "Sarah"];
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var max = 25; // fixed for simplicity
var obj = {};
obj[id] = max;
var maxObj = _.findIndex(people['scores'], obj);
}

How do I programmatically capture and replicate Ai path shape?

I'm using ExtendScript for scripting Adobe Illustrator. I was wondering if there was a sneaky way or a script available to programmatically capture and then replicate a path shape, sort of JavaScript's .toSource() equivalent.
Thanks
Try this:
main();
function main(){
var doc = app.activeDocument; // get the active doc
var coords = new Array(); // make a new array for the coords of the path
var directions = new Array();
var sel = doc.selection[0];// get first object in selection
if(sel == null) {
// check if something is slected
alert ("You need to sevlect a path");
return;
}
var points = sel.pathPoints;// isolate pathpoints
// loop points
for (var i = 0; i < points.length; i++) {
// this could be done in one lines
// just to see whats going on line like
//~ coords.push(new Array(points[i].anchor[0],points[i].anchor[1]));
var p = points[i]; // the point
var a = p.anchor; // his anchor
var px = a[0];// x
var py = a[1]; // y
var ldir = p.leftDirection;
var rdir = p.rightDirection;
directions.push(new Array(ldir,rdir));
coords.push(new Array(px,py));// push into new array of array
}
var new_path = doc.pathItems.add(); // add a new pathitem
new_path.setEntirePath(coords);// now build the path
// check if path was closed
if(sel.closed){
new_path.closed = true;
}
// set the left and right directions
for(var j = 0; j < new_path.pathPoints.length;j++){
new_path.pathPoints[j].leftDirection = directions[j][0];
new_path.pathPoints[j].rightDirection = directions[j][1];
}
}

JScript.NET private variables

I'm wondering about JScript.NET private variables. Please take a look on the following code:
import System;
import System.Windows.Forms;
import System.Drawing;
var jsPDF = function(){
var state = 0;
var beginPage = function(){
state = 2;
out('beginPage');
}
var out = function(text){
if(state == 2){
var st = 3;
}
MessageBox.Show(text + ' ' + state);
}
var addHeader = function(){
out('header');
}
return {
endDocument: function(){
state = 1;
addHeader();
out('endDocument');
},
beginDocument: function(){
beginPage();
}
}
}
var j = new jsPDF();
j.beginDocument();
j.endDocument();
Output:
beginPage 2
header 2
endDocument 2
if I run the same script in any browser, the output is:
beginPage 2
header 1
endDocument 1
Why it is so??
Thanks,
Paul.
Just a guess, but it appears that JScript.NET doesn't support closures the same way as EMCAScript, so the state variable in endDocument() isn't referencing the private member of the outer function, but rather an local variable (undeclared). Odd.
You don't have to use new when calling jsPDF here since you're using a singleton pattern. jsPDF is returning an object literal so even without new you'll have access to the beginPage and endDocument methods. To be perfectly honest I don't know what the specifications call for when using new on a function that returns an object literal so I'm not sure if JScript.NET is getting it wrong or the browser. But for now try either getting rid of the new before jsPDF() or change your function to this:
var jsPDF = function(){
var state = 0;
var beginPage = function(){
state = 2;
out('beginPage');
};
var out = function(text){
if(state == 2){
var st = 3;
}
MessageBox.Show(text + ' ' + state);
};
var addHeader = function(){
out('header');
};
this.endDocument = function(){
state = 1;
addHeader();
out('endDocument');
};
this.beginDocument: function(){
beginPage();
};
}
That will allow you to use the new keyword and create more than one jsPDF object.
I've come across the same problem. In the following code, the closure bound to fun should contain only one variable called result. As the code stands, the variable result in the function with one parameter seems to be different to the result variable in the closure.
If in this function the line
result = [];
is removed, then the result in the line
return result;
refers to the result in the closure.
var fun = function() {
var result = [];
// recursive descent, collects property names of obj
// dummy parameter does nothing
var funAux = function(obj, pathToObj, dummy) {
if (typeof obj === "object") {
for (var propName in obj) {
if (obj.hasOwnProperty(propName)) {
funAux(obj[propName], pathToObj.concat(propName), dummy);
}
}
}
else {
// at leaf property, save path to leaf
result.push(pathToObj);
}
}
return function(obj) {
// remove line below and `result' 3 lines below is `result' in closure
result = []; // does not appear to be bound to `result' above
funAux(obj, [], "dummy");
return result; // if result 2 lines above is set, result is closure is a different variable
};
}();