C
Join ServerC#
help
❔ LINQ build an array with an arbitrary value at the start
BBenMcLean1/29/2023
So, I want to make a palette that's an array of
Question: How could I get this same result with LINQ?
int
s where index 0 is equal to 0 and the rest repeat a rainbow pattern.public static readonly ReadOnlyCollection<int> Rainbow = Array.AsReadOnly(new int[7]
{ // Just a color test, not a political statement.
unchecked((int)0xFF0000FF),//Red
unchecked((int)0xFFA500FF),//Orange
unchecked((int)0xFFFF00FF),//Yellow
0x00FF00FF,//Green
0x0000FFFF,//Blue
0x4B0082FF,//Indigo
unchecked((int)0x8F00FFFF)//Violet
});
public static int[] RainbowPalette()
{
int[] palette = new int[byte.MaxValue];
for (int index = 1; index < palette.Length; index++)
palette[index] = Rainbow[(index - 1) % Rainbow.Count];
return palette;
}
Question: How could I get this same result with LINQ?
AAngius1/29/2023
Working with HSV colors would be the easiest, since you'd only need to increment the hue
BBenMcLean1/29/2023
The colors aren't the point, it's a LINQ question
AAngius1/29/2023
Well, assuming HSV...
var colors = Enumerable.Range(0, 255)
.Select(hue => new Hsv(hue, 255, 255))
.ToArray();
BBenMcLean1/29/2023
That isn't the same result. That would return an
IEnumerable<HSV>
. The question is how to return an int[]
BBenMcLean1/29/2023
Also, that doesn't include the
0
value at the start.AAngius1/29/2023
It would return
Hsv[]
strictly speakingAAngius1/29/2023
And I thought the colors weren't the point?
BBenMcLean1/29/2023
The 0 value at the start is the point
AAngius1/29/2023
Uh,
Enumerable.Range(0, someMaxValue)
will give you integers from 0
to some max value...?BBenMcLean1/29/2023
See, my for loop starts with 1. It leaves index zero blank, then it repeats the rainbow pattern from 1 to 255,
EEro1/29/2023
So start at 1 instead of 0?
AAngius1/29/2023
If so,
Enumerable.Range(1, max)
AAngius1/29/2023
Ah, wait, then
1
would be at index 0
and you don't want thatBBenMcLean1/29/2023
I guess I could check it like
but it seems like there should be some kind of way to do something like
Enumerable.Range(0,255).Select(i => i == 0 ? 0 : Rainbow[(i - 1) % Rainbow.Count])
but it seems like there should be some kind of way to do something like
.Add(0).Add(Enumerable.Range(1, 255).Select(i => Rainbow[i % Rainbow.Count])
and then it could concatonate the zero at the start before getting into the range ... maybe?AAngius1/29/2023
Generate a list of colors, then
list.Insert(0, 0)
AAngius1/29/2023
Will insert
0
at the start of the list and shift everything else upBBenMcLean1/29/2023
Oh, OK, that makes sense.
AAngius1/29/2023
So
var colors = Enumerable.Range(0, 255)
.Select(x => Rainbow[x % Rainbow.Count])
.ToList()
.Insert(0, 0);
AAngius1/29/2023
Something like this
EEro1/29/2023
Insert doesn't return the list
BBenMcLean1/29/2023
that except 254, because otherwise you end up with a list that's 257 items long
AAngius1/29/2023
Ah, right
EEro1/29/2023
Honestly anything i think of makes me fall back to "this would be better if it's just a loop"
BBenMcLean1/29/2023
I went with
public static readonly int[] RainbowPalette =
Enumerable.Range(0, byte.MaxValue)
.Select(i => i == 0 ? 0 : Rainbow[(i - 1) % Rainbow.Count])
.ToArray();
BBenMcLean1/29/2023
actually I went with LINQ because I didn't want it to be a method
BBenMcLean1/29/2023
just wanted it to be a data member if that makes sense
EEro1/29/2023
Bad thinking, stop doing that
DD.Mentia1/29/2023
That works. I agree, better as a loop. And also we could find a thousand ways to do it, increasingly complex 😛
Like if you took the Math.Sign of i and multiplied it by the value, no conditional
Like if you took the Math.Sign of i and multiplied it by the value, no conditional
DD.Mentia1/29/2023
You can populate your data member via a method. You want it to be a method because it makes it much easier to change it later, if you want the colors to be different or come in from somewhere else, and because realistically all of these are just really confusing looking
EEro1/29/2023
I would just
private int[]? _palette;
public int[] Palette
{
get
{
if (_palette is not null)
return _palette;
_palette = new int[255];
// rainbow thing, loop, populate
return _palette;
}
}
EEro1/29/2023
Make it readonly or whatever if you need
AAccord1/30/2023
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.