# Convert empty tuple to an array of a specific type

**URL:** <https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418>\
**Category:** Help & Support\
**Created:** [November 20, 2024, 7:02am UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418 "2024-11-20T07:02:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [November 20, 2024, 7:02am UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418/1 "2024-11-20T07:02:52Z")

</div>

Is there a way to convert an empty `Tuple` into an array of a specified type?

I’m generating documentation based on user-definable commands. The argument declaration for the commands must be a `Tuple` because they’re splatted and passed to a method on the command. I need to be able to turn that tuple into an array, but if the command doesn’t take any arguments, the `Tuple` is empty, and `tuple.map { |e| foo(e) }.to_a` returns an `Array(NoReturn)` no matter what I do, including manual `.as` inside the block and on the array.

Is there a way to go from `Tuple()` to `Array(T)` where `T` _isn’t_`NoReturn`? Or do I have to do the `empty?` check manually?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [November 20, 2024, 2:02pm UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418/2 "2024-11-20T14:02:03Z")

</div>

> [@jgaskins](#):
>
> and `tuple.map { |e| foo(e) }.to_a` returns an `Array(NoReturn)` no matter what I do, including manual `.as` inside the block and on the array.

This makes sense since the tuple is empty the map technically never runs at all and just returns another empty tuple.

I think your best bet is use a method with a freevar and check the size of the tuple type and key off that. E.g.

```crystal
tup = Tuple.new
tup2 = {0, "foo"}

def tup_to_array(tup : Tuple(*T)) : Array forall T
  {% if 0 == T.size %}
    [] of String
  {% else %}
    [] of Union(*T)
  {% end %}
end

pp tup_to_array(tup).class # => Array(String)
pp tup_to_array(tup2).class # => Array(Int32 | String)

```

But what’s the reasoning for needing it to be an array?

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [November 20, 2024, 3:03pm UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418/3 "2024-11-20T15:03:08Z")

</div>

Explicitly creating the array may be helpful:

```crystal
ary = [] of T
tuple.each do |e|
  ary << foo(e)
end

```

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [November 20, 2024, 4:19pm UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418/4 "2024-11-20T16:19:18Z")

</div>

> [@Blacksmoke16](#):
>
> what’s the reasoning for needing it to be an array?

I’m passing the result to an object constructor that only accepts an `Array` because it’s a `JSON::Serializable` type. This object is part of a shard, but creating the data structure happens in my application.

> [@straight-shoota](#):
>
> Explicitly creating the array may be helpful:
> 
> ```auto
> ary = [] of T
> tuple.each do |e|
> ary << foo(e)
> end
> 
> ```

Good call. I get so used to using `map` that I sometimes forget that we can just do it the old-fashioned way.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [November 20, 2024, 4:22pm UTC](https://forum.crystal-lang.org/t/convert-empty-tuple-to-an-array-of-a-specific-type/7418/5 "2024-11-20T16:22:27Z")

</div>

One thing I did for Athena is keep a reference to the `Tuple` type itself, but store the values as an `Array`, then use [Tuple(\*T) - Crystal 1.14.0](https://crystal-lang.org/api/1.14.0/Tuple.html#from%28array%3AArray%29%3Aself-class-method) to build out the tuple to splat. It’s a pretty slick method. Not sure if it makes sense for your use case tho.
