Defining an array of anonymous objects in CoffeeScript - coffeescript

How do I define an array of anonymous objects in CoffeeScript? Is this possible at all, using the YAML syntax?
I know that having an array of named objects is quite easy:
items:[
item1:
name1:value1
item2:
name:value2
]
However, it would be a bit trickier, if those two objects had no names

Simple -- place a comma by itself in a column lower than that in which you define your objects.
a = [
nameA1: valueA1
nameA2: valueA2
nameA3: valueA3
,
nameB1: valueB1
nameB2: valueB2
nameB3: valueB3
]
Will become:
var a;
a = [
{
nameA1: valueA1,
nameA2: valueA2,
nameA3: valueA3
}, {
nameB1: valueB1,
nameB2: valueB2,
nameB3: valueB3
}
];

You can also add a coma between each object: 
items:[
item1:
name1:value1
,
item2:
name:value2
]

you can't:
this is some tricks:
items:[
(name:"value1")
(name:"value2")
]
another
items:[
true && name:"value1"
true && name:"value2"
]
this is the best:
items:[
{name:"value1"}
{name:"value2"}
]

I think the comma solution is better, but I figured I'd add this for completeness:
a = [
{
nameA1: valueA1
nameA2: valueA2
nameA3: valueA3
}
{
nameB1: valueB1
nameB2: valueB2
nameB3: valueB3
}
]

You can define variable while defining array, so an ugly answer would be:
a =
items: [
item1 =
name: 'value1'
item2 =
name: 'value2'
]
It would work, but you may get warnings about "defined, but not used variables (item1, item2)". Better way would be to use underscore, variable used to omit not used variables:
a =
items: [
_ =
name: 'value1'
_ =
name: 'value2'
]
console.log JSON.stringify(a) will produce this:
{
"items":[
{
"name":"value1"
},{
"name":"value2"
}
]
}

I'm very happy to report after a bit of fiddling that I could get this to compile just right:
items: [
nameA: subA
nameB: subB
,
nameX: subX
nameY: subY
]
It results it just what you'd expect: a list of two anonymous objects.

I ran into a related problem and found this solution. If you want an array of many single k/v objects without braces, just indent some of them. Seems to do the trick.
data = [
"2013-09-25T16:46:52.636Z":3,
"2013-09-25T16:47:52.636Z":6,
"2013-09-25T16:48:52.636Z":2,
"2013-09-25T16:49:52.636Z":7,
"2013-09-25T16:50:52.636Z":5,
"2013-09-25T16:51:52.636Z":2,
"2013-09-25T16:52:52.636Z":1,
"2013-09-25T16:53:52.636Z":3,
"2013-09-25T16:54:52.636Z":8,
"2013-09-25T16:55:52.636Z":9,
"2013-09-25T16:56:52.636Z":2,
"2013-09-25T16:57:52.636Z":5,
"2013-09-25T16:58:52.636Z":7
]
Produces:
coffee> data
[ { '2013-09-25T16:46:52.636Z': 3 },
{ '2013-09-25T16:47:52.636Z': 6 },
{ '2013-09-25T16:48:52.636Z': 2 },
{ '2013-09-25T16:49:52.636Z': 7 },
{ '2013-09-25T16:50:52.636Z': 5 },
{ '2013-09-25T16:51:52.636Z': 2 },
{ '2013-09-25T16:52:52.636Z': 1 },
{ '2013-09-25T16:53:52.636Z': 3 },
{ '2013-09-25T16:54:52.636Z': 8 },
{ '2013-09-25T16:55:52.636Z': 9 },
{ '2013-09-25T16:56:52.636Z': 2 },
{ '2013-09-25T16:57:52.636Z': 5 },
{ '2013-09-25T16:58:52.636Z': 7 } ]
It's counter-intuitive to me; you'd think that this would make sub-objects but I think the comma at the end of the line tells it to stop making properties on that object.

Not an answer to the OP's question, but just in case you're here for the same reason I was... If you're low on Mountain Dew and use '=' instead of ':', then Coffeescript will turn your array of objects into a flat array without a compile error:
data = [
one='one'
two='two'
,
one='1'
two='2'
]
Produces
['one', 'two', '1', '2']
Insert more Mountain Dew and replace the '=' with ':'.

Why not:
list = []
list.push
prop1: val
prop2: val
list.push
prop1: val
prop2: val
It's still a huge improvement to me over js, very easy to read, minimal and pretty safe to write.

Related

JSONB filter on select via Supabase

I have such a logic (attributes column's type is JSONB - array of objects) that works:
But I want to implement logical OR here if trait_type is equal ... not AND:
JSONB's column structure:
[
{
"value":"Standard Issue Armor 1 (Purple)",
"trait_type":"Clothes"
},
{
"value":"Standard Issue Helmet 1 (Red)",
"trait_type":"Full Helmet"
},
{
"value":"Chrome",
"trait_type":"SmartSkin"
},
{
"value":"Base Drone (Blue)",
"trait_type":"Drone"
},
{
"value":"Thick",
"trait_type":"Eyebrows"
}
]
How that could be done?
Thanks in advance!
I didn't verify the code, so might not work, but I believe at least is in the right direction. You can use the .or() filter to connect multiple filters with logical or operator. For contains(), you can use the cs keyword inside the or filter like this:
const { data, error } = await supabase.from('NTFs')
.select('name, id_in_collection, owner_address')
.eq('collection_id', Number(id))
.contains('attributes', JSON.stringify([{trait_type: 'SmartSkin', value: 'Chrome'}]))
.or(`attributes.cs.${JSON.stringify([{trait_type: 'Drone', value: 'Armed Drone (Blue)'}])}`, `attributes.cs.${JSON.stringify([{trait_type: 'Drone', value: 'Armed Drone (Green)'}])}`)
.order('id_in_collection')
.range(fromIndex, toIndex)

Scala - Merge sub lists into a single list contained inside values of a map

I am trying to solve the below problem in a functional way. Given I have a data structure that looks like below:
final case class ActionConfiguration(
configId: Int,
actions: List[Action],
`type`: String,
time: String,
weekday: Option[List[Int]]
)
And I have a Map that has the following signature: Map[TargetLocation, List[ActionConfiguration]]
As you can see I want to execute some actions at a target location at a configured time and weekday. The way it is currently working is, if I have a set of actions to be performed at the same time and day, I am populating only one action in the actions list and creating many ActionConfiguration objects that may have the same configured time and day. My goal is to utilize the Actions list to populate all the actions that I want to execute inside a single ActionConfiguration.
As an example, given the situation today that I have this:
"ActionConfiguration":[
{
"configId":1,
"actions":[
{
"cmd":"doAction1"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":2,
"actions":[
{
"cmd":"doAction2"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":3,
"actions":[
{
"cmd":"doAction3"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":4,
"actions":[
{
"cmd":"doAction4"
}
],
"type":"weekly",
"time":"09:00",
"weekday":[
5
]
},
{
"configId":5,
"actions":[
{
"cmd":"doAction5"
}
],
"type":"weekly",
"time":"22:00",
"weekday":[
4
]
}
]
I want to achieve this:
"ActionConfiguration": [
{
"configId": 1,
"actions": [
{
"cmd": "doAction1"
},
{
"cmd": "doAction2"
},
{
"cmd": "doAction3"
},
{
"cmd": "doAction4"
}
],
"type": "weekly",
"time": "09:00",
"weekday": [
5
]
},
{
"configId": 2,
"actions": [
{
"cmd": "doAction5"
}
],
"type": "weekly",
"time": "22:00",
"weekday": [
4
]
}
]
As you can see I want merge the actions that needs to be performed at the same time into a single list. I am coming from a Java background and currently working on Scala. I know how to solve this problem in Java style, but I am looking for some ways how we can solve this in a functional style as I am very interested to learn functional programming.
Assuming there's a constructor for ActionConfiguration that takes the members in the order below, this probably works (I just typed it here, I didn't compile or test it):
val mergedList = listofActionConfigurations
.groupBy(a => (a.configId, a.time, a.type, a.weekday))
.values
.map(la => (la.head, la.map(_.actions).flatten))
.map(t => new ActionConfiguration(t._1.configId, t._1.time, t._1.type, t._1.weekday, t._2))
.toList
What's happening here?
We group the list of ActionConfigurations by a key created by tupling all fields of ActionConfigurations except the actions list.
Then we throw away the keys and take just the values, which is some Set-like collection containing Lists of ActionConfigurations.
We map over that collection, and for each list of ActionConfigurations in it, we grab the first element of the list (.head) and then we map each ActionConfiguration in the list to its list of actions, and then we flatten the resulting list of lists. We yield a tuple of the head item and the flattened list.
We then map the tuple (head, list of actions) to a new ActionConfiguration with all the members of head except its list of actions, and the flattened list of actions as the new ActionConfiguration's action list.
Finally, since we probably still have a Set-like collection, we explicitly turn it into a List.
It takes much longer to explain than to write. :)
Note that the Scala library docs make no guarantees about the order of the actions in the merged actions list (but the implementation seems to be order-preserving); if you require it to be ordered, sort after flattening then action lists.
It seems all you need is groupMapReduce to create a Map[TargetLocation, List[Action]] which you can later map if you really want a Map[TargetLocation, List[ActionConfiguration]]
configurations.groupMapReduce(
ac => (ac.configId, ac.time, ac.type, ac.weekday)
)(
ac => ac.actions
)(
(l1, l2) => l1 reverse_::: l2 // Similar to l1 ++ l2 but more efficient, although the order changes.
)

Trouble adding to hash in perl

I am reading a file replacing data and returning output to json. When I try to add a new item to the hash I get the following error. Not a HASH reference When I use ref() I am getting HASH as the type.
I have tried.
my $json_data = decode_json($template);
$json_data->{CommandCenters}{NewItem} = ["haha","moredata"];
Gives the not a hash reference error
The $json_data is below.
{
"Location":"Arkansas",
"CommandCenters": [
{
"secretary": "jill",
"janitor": "mike"
}
],
}
I am looking for the following output after I add the element.
{
"Location":"Arkansas",
"city": "little rock"
"CommandCenters": [
{
"secretary": "jill",
"janitor": "mike"
},
{
"NewItem":["whatever","more data"]
}
],
}
If I use $json_data->{CommandCenters}[0]{NewItem} = ['whatever','sure']; I do not get an error but I get unexpected results.
The data is added but in the incorrect slot.
"commandcenters":
[
"secretary":"jill",
"janitor": "mike",
"newitem":
[
"whatever","sure"
],
]
To add a new element to an array, use push. As we
're dealing with an array reference, we need to dereference it first.
push #{ $json_data->{CommandCenters} }, { NewItem => ["haha", "moredata"] };
When I try to add a new item to the hash I get the following error. Not a HASH reference When I use ref() I am getting HASH as the type.
Attention to detail is a vital skill for a successful programmer. And you're missing something subtle here.
When you use ref(), I assume you're passing it your $json_data variable. And that is, indeed, a hash reference. But the line that generates your Not a HASH reference is this line:
$json_data->{CommandCenters}{NewItem} = ["haha","moredata"];
And that's not just treating $json_data as a hash reference ($json_data->{...}) it's also treating $json_data->{CommandCenters} as a hash reference. And that's where your problem is. $json_data->{CommandCenters} is an array reference, not a hash reference. It's generated from the bit of your JSON that looks like this:
"CommandCenters": [
{
"secretary": "jill",
"janitor": "mike"
}
]
And those [ .. ] mark it as an array not a hash. You can't add a new key/value pair to an array; you need to push() new data to the end of the array. Something like:
push #{ $json_data->{CommandCenters} }, { NewItem => ["haha", "moredata"] };
That will leave you with this data structure:
$VAR1 = {
'CommandCenters' => [
{
'janitor' => 'mike',
'secretary' => 'jill'
},
{
'NewItem' => [
'haha',
'moredata'
]
}
],
'Location' => 'Arkansas'
};
And encode_json() will turn that into the JSON that you want.

mongoDB collection.findOne() update the query with its own results

I have a query like this one :
.findOne( {
_id: myObjectId,
}, {
fields: {
smallSingleValue: 1,
HUDGE_OBJECT: 1,
}
} );
I do not need the entire HUDGE_OBJECT (it is roughly 1 Mo), I need HUDGE_OBJECT[ smallSingleValue ] ( less than a Ko ).
Right now, I can make that request and get the entire HUDGE_OBJECT, or make two requests ; one the guet the smallSingleValue and the other one to get the HUDGE_OBJECT[ smallSingleValue ].
Both solution are crapy.
Is there a way to do something like that :
fields: {
smallSingleValue: 1,
`HUDGE_OBJECT.${ $smallSingleValue }`: 1,
}
Obviously not with that syntax, but you get the idea.
I tried aggregation, but it’s probably not the solution.
Does the projection operator allows it ?
https://docs.mongodb.com/manual/reference/operator/projection/positional/
EDIT FOR THE COMMENTS :
Example of data :
{
_id: xxx,
firstName: xxx,
lastName: xxx,
currentLevel: bar, // <- that one is important
progress: {
foo: { big object },
bar: { big object },
baz: { big object },
...
}
}
What I need :
{
firstName: xxx,
lastName: xxx,
currentLevel: bar,
progress: {
bar: { big object },
}
}
But the question is : performance wise, is it better to just get the entire object (easy query) or to get a truncated object (more complex query but passing a bigger object) ? There are 50 «levels».
I don’ remember what I tried with the aggregation :x but it seemed to be a bad idea.

Sails Waterline "Or" clause not working

I tried a lot of time to figure out getting an OR clause working in sails without success.
I am using Sails-MySql adapter.
Have anyone of you done anything like this already? I would appreciate some help.
Basically this is what I want to do:
Do an OR clause on a set of fields along with an AND on another set of fields.
Something like this:
FdbDevice
.find()
.where(or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)
.exec
In this particular case, here is how I would do it:
// Each element in the array is treated as 'or'
var possibleDeviceCategories = [
'cardiology valve bioprosthesis',
'nephrology haemodialysis catheter'
];
FdbDevice
.find({
deviceCategory: possibleDeviceCategories,
catalogNumber: 'Z286004',
modelNumber: 'Z286004'
})
.exec(cb);
Check out the docs for more informations about the Waterline's query language.
you can try something like that, into the find:
FdbDevice
.find({or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)