# Collect single item

hey, just a simple question about using collect.

i have this function:

``````(
var f = { |freqs|
freqs.collect { |freq|
freq * (1..16);
}.flop;
};

var freqs = [440, 440, 440, 440, 440];

f.(freqs);
)
``````

and would also like to have the possibility to just pass a single item instead of an array.
The result should look like this:

``````(
var f = { |freq|
freq * (1..16);
};

var freq = 440;

f.(freq);
)
``````

is it possible to have the first one behave like the second one when only a single item is passed? thanks

do i have to use `if` here?

``````(
var f = { |freqs|
var ratios = (1..16);
if( freqs.size == 0,

{
freqs * ratios
},

{
freqs.collect { |freq|
freq * ratios;
}.flop;
}
);

};

var freqs = [440, 440, 440, 440, 440];

f.(freqs);
)
``````

Something like that:

``````(
var f = { |freq|
if(freq.isArray)
{
freq.collect{|frq|frq * (1..16)}.flop
}
{
freq * (1..16)
}
};
)
``````

thanks i was also thinking about this and thought there would be another solution beside `if`.

Without `if` the result needs to be â€śnormalizedâ€ť as an array of arrays:

``````(
var f = { |freq|
freq.asArray.collect{|frq|frq * (1..16)}.flop
};
)
``````

It can be helpful to write up a spec of exactly what you want for types of input.

Presumably:

• `f.value(number)` â€“ youâ€™d like an array consisting of each 1â€¦16 element times the number.

• `f.value(array)` â€“ an array of arrays, consisting of each array element times 1â€¦16â€¦ that is, the two arrays would be multiplied into a table â€“ 1â€¦16 across the top, the input array down the side.

This isnâ€™t convenient to search in the help, but in fact SC does support table-style math ops on arrays.

``````f = { |x| x *.t (1..16) };
``````

(BTW what if you table-multiply a number by (1â€¦16)? It just gives you a single row, not as a nested array. So it matches the spec.)

:

1 Like

thanks, there is one adjustment to the specifications:

f.value(number) should return a single array with 1â€¦16 elements times the number. check!

but f.value(array) should return an array of 16 arrays, where each array of arrays has input.size times the n-element

using flop gives me the desired result for f.value(array)

``````(
f = { |x|
(x *.t (1..16)).flop;
};

f.([440, 440, 440, 440, 440]);
)
``````

but for f.value(number) it should return a flat array, so no flop:

``````(
f = { |x|
(x *.t (1..16));
};

f.(440);
)
``````

Go back and take another look at my post: â€ś1â€¦16 across the top, the input array down the side.â€ť

Now look at the expression: `f = { |x| x *.t (1..16) };` â€“ so the â€śacross the topâ€ť (rows) is the second operand, and â€śdown the sideâ€ť (columns) is the first operand.

What youâ€™re saying here is that you want 1â€¦16 down the side (columns), and the input array across the top (rows).

And we know that the expression is written in terms of `columns *.t rows`.

Nowâ€¦ given that, do you think you can adapt the `*.t` expression on your own?

hjh

1 Like

thank you very much. it works for both cases when exchanging the input data for columns and rows:

`f = { |x| (1..16) *.t x };`