Can destructuring assignment be used to effect a projection in CoffeeScript?
-
02-03-2021 - |
Pregunta
I'm having some trouble understanding destructuring assignment in CoffeeScript. The documentation contains a couple of examples which together seem to imply that renaming objects during assignment can be used to project (i.e. map, translate, transform) a source object.
I am trying to project a = [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
into b = [ { x: 1 }, { x: 2 } ]
. I've tried the following without success; I've clearly misunderstood something. Can anyone explain whether this is possible?
My Poor Attempts That Don't Return [ { x: 1 }, { x: 2 } ]
a = [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
# Huh? This returns 1.
x = [ { Id } ] = a
# Boo! This returns [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
y = [ { x: Id } ] = a
# Boo! This returns [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
z = [ { Id: x } ] = a
CoffeeScript's Parallel Assignment Example
theBait = 1000
theSwitch = 0
[theBait, theSwitch] = [theSwitch, theBait]
I understand this example as implying that variables can be renamed which in this case is used to perform a swap.
CoffeeScript's Arbitrary Nesting Example
futurists =
sculptor: "Umberto Boccioni"
painter: "Vladimir Burliuk"
poet:
name: "F.T. Marinetti"
address: [
"Via Roma 42R"
"Bellagio, Italy 22021"
]
{poet: {name, address: [street, city]}} = futurists
I understand this example as defining a selection of properties from an arbitrary object which includes assigning the elements of an array to variables.
Update: Using thejh's Solution to Flatten an Array of Nested Objects
a = [
{ Id: 0, Name: { First: 'George', Last: 'Clinton' } },
{ Id: 1, Name: { First: 'Bill', Last: 'Bush' } },
]
# The old way I was doing it.
old_way = _.map a, x ->
{ Id: id, Name: { First: first, Last: last } } = x
{ id, first, last }
# Using thejh's solution...
new_way = ({id, first, last} for {Id: id, Name: {First: first, Last: last}} in a)
console.log new_way
Solución
b = ({x} for {Id: x} in a)
works:
coffee> a = [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
[ { Id: 1, Name: 'Foo' },
{ Id: 2, Name: 'Bar' } ]
coffee> b = ({x} for {Id: x} in a)
[ { x: 1 }, { x: 2 } ]
coffee>
Otros consejos
CoffeeScript Cookbook solves exactly the same problem as yours - solution is map:
b = a.map (hash) -> { x: hash.id }
c = ({ x: hash.id } for hash in a)
You can check this fiddle online on CoffeScript homepage (uses console.info to show results).
EDIT:
To make it destrutive just assign mapped variable a
to itself:
a = a1 = [ { Id: 1, Name: 'Foo' }, { Id: 2, Name: 'Bar' } ]
a = a.map (hash) -> { x: hash.Id }
console.info a;
a1 = ({ x: hash.Id } for hash in a1)
console.info a1;