在 CoffeeScript 中定义匿名对象数组

如何在 CoffeeScript 中定义匿名对象数组? 是否可以使用 YAML 语法?

我知道拥有一个命名对象数组非常容易:

items:[
item1:
name1:value1
item2:
name:value2
]

然而,如果这两个对象没有名字,那么就会有点棘手了

26695 次浏览

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"}
]

You can also add a coma between each object: 

items:[
item1:
name1:value1
,
item2:
name:value2
]

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
}
];

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
}
]

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 ':'.

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.

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.