mirror of
https://github.com/sphildreth/roadie
synced 2025-02-16 13:08:25 +00:00
Finaly random is shuffled.
This commit is contained in:
parent
17c29503af
commit
fc548e1d84
7 changed files with 146 additions and 72 deletions
|
@ -84,7 +84,31 @@ namespace Roadie.Library.Tests
|
|||
},
|
||||
new Models.TrackList
|
||||
{
|
||||
Track = new Models.DataToken { Value = "A2_R5", Text = "A2_R5" },
|
||||
Track = new Models.DataToken { Value = "A2_R5_1", Text = "A2_R5_1" },
|
||||
Artist = new Models.ArtistList
|
||||
{
|
||||
Artist = new Models.DataToken { Value = "A2", Text = "A2" }
|
||||
},
|
||||
Release = new Models.Releases.ReleaseList
|
||||
{
|
||||
Release = new Models.DataToken { Value = "R5", Text = "R5" }
|
||||
}
|
||||
},
|
||||
new Models.TrackList
|
||||
{
|
||||
Track = new Models.DataToken { Value = "A2_R5_2", Text = "A2_R5_2" },
|
||||
Artist = new Models.ArtistList
|
||||
{
|
||||
Artist = new Models.DataToken { Value = "A2", Text = "A2" }
|
||||
},
|
||||
Release = new Models.Releases.ReleaseList
|
||||
{
|
||||
Release = new Models.DataToken { Value = "R5", Text = "R5" }
|
||||
}
|
||||
},
|
||||
new Models.TrackList
|
||||
{
|
||||
Track = new Models.DataToken { Value = "A2_R5_3", Text = "A2_R5_3" },
|
||||
Artist = new Models.ArtistList
|
||||
{
|
||||
Artist = new Models.DataToken { Value = "A2", Text = "A2" }
|
||||
|
@ -177,6 +201,18 @@ namespace Roadie.Library.Tests
|
|||
{
|
||||
Release = new Models.DataToken { Value = "R12", Text = "R12" }
|
||||
}
|
||||
},
|
||||
new Models.TrackList
|
||||
{
|
||||
Track = new Models.DataToken { Value ="A10_R13", Text = "A10_R13" },
|
||||
Artist = new Models.ArtistList
|
||||
{
|
||||
Artist = new Models.DataToken { Value = "A10", Text = "A10" }
|
||||
},
|
||||
Release = new Models.Releases.ReleaseList
|
||||
{
|
||||
Release = new Models.DataToken { Value = "R13", Text = "R13" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -184,8 +220,8 @@ namespace Roadie.Library.Tests
|
|||
var lastTrack = shuffledTracks.First();
|
||||
foreach(var track in shuffledTracks.Skip(1))
|
||||
{
|
||||
Assert.NotEqual(track.Artist.Artist.Text, lastTrack.Artist.Artist.Text);
|
||||
Assert.NotEqual(track.Release.Release.Text, lastTrack.Release.Release.Text);
|
||||
Assert.False(track.Artist.Artist.Text == lastTrack.Artist.Artist.Text &&
|
||||
track.Release.Release.Text == lastTrack.Release.Release.Text);
|
||||
lastTrack = track;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -23,5 +24,7 @@ namespace Roadie.Library.Extensions
|
|||
}
|
||||
return string.Join(", ", timings);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -6,32 +7,25 @@ namespace Roadie.Library.Extensions
|
|||
{
|
||||
public static class ListExt
|
||||
{
|
||||
public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
|
||||
public static void Shuffle<T>(this IList<T> list)
|
||||
{
|
||||
var rnd = new Random();
|
||||
return source.OrderBy(item => rnd.Next());
|
||||
int n = list.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = StaticRandom.Instance.Next(n + 1);
|
||||
T value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
}
|
||||
|
||||
//public static void Shuffle<T>(this IList<T> list)
|
||||
//{
|
||||
// var n = list.Count;
|
||||
// var rnd = new Random();
|
||||
// while (n > 1)
|
||||
// {
|
||||
// var k = rnd.Next(0, n) % n;
|
||||
// n--;
|
||||
// var value = list[k];
|
||||
// list[k] = list[n];
|
||||
// list[n] = value;
|
||||
// }
|
||||
//}
|
||||
|
||||
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
|
||||
{
|
||||
T[] elements = source.ToArray();
|
||||
for (int i = elements.Length - 1; i >= 0; i--)
|
||||
{
|
||||
int swapIndex = rng.Next(i + 1);
|
||||
int swapIndex = StaticRandom.Instance.Next(i + 1);
|
||||
yield return elements[swapIndex];
|
||||
elements[swapIndex] = elements[i];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
using Mapster;
|
||||
using Newtonsoft.Json;
|
||||
using Roadie.Library.Utility;
|
||||
using System;
|
||||
|
||||
namespace Roadie.Library.Models
|
||||
{
|
||||
|
@ -46,6 +49,18 @@ namespace Roadie.Library.Models
|
|||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Random int to sort when Random Request
|
||||
/// </summary>
|
||||
[AdaptIgnore]
|
||||
[JsonIgnore]
|
||||
public int RandomSortId { get; set; }
|
||||
|
||||
public DataToken()
|
||||
{
|
||||
RandomSortId = StaticRandom.Instance.Next();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Text [{Text}], Value [{Value}]";
|
||||
|
|
|
@ -74,36 +74,60 @@ namespace Roadie.Library.Models
|
|||
|
||||
public override int GetHashCode() => this.Artist?.Artist?.Value.GetHashCode() + this.Release?.Release?.Value.GetHashCode() + this.Track?.Value.GetHashCode() ?? 0;
|
||||
|
||||
public static IEnumerable<int> AllIndexesOfArtist(IEnumerable<TrackList> tracks, string artistId)
|
||||
{
|
||||
if(tracks == null || !tracks.Any())
|
||||
{
|
||||
return Enumerable.Empty<int>(); ;
|
||||
}
|
||||
return tracks.Select((b, i) => b.Artist?.Artist?.Value == artistId ? i : -1).Where(i => i != -1).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<int> AllIndexesOfRelease(IEnumerable<TrackList> tracks, string releaseId)
|
||||
{
|
||||
if (tracks == null || !tracks.Any())
|
||||
{
|
||||
return Enumerable.Empty<int>(); ;
|
||||
}
|
||||
return tracks.Select((b, i) => b.Release?.Release?.Value == releaseId ? i : -1).Where(i => i != -1).ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that the given list is sorted so that Artist and Release don't repeat in sequence.
|
||||
/// </summary>
|
||||
public static IEnumerable<TrackList> Shuffle(IEnumerable<TrackList> tracks)
|
||||
{
|
||||
var shuffledTracks = new List<TrackList>(tracks);
|
||||
Models.TrackList lastTrack = shuffledTracks.Skip(1).First();
|
||||
foreach (var track in tracks)
|
||||
|
||||
var shuffledTracks = new List<TrackList>();
|
||||
var skippedTracks = new List<TrackList>();
|
||||
foreach(var track in tracks)
|
||||
{
|
||||
if (lastTrack?.Artist?.Artist?.Value == track?.Artist?.Artist?.Value ||
|
||||
lastTrack?.Release?.Release?.Value == track?.Release?.Release?.Value)
|
||||
var trackArtist = track.Artist?.Artist?.Value;
|
||||
var trackRelease = track.Release?.Release?.Value;
|
||||
if (!shuffledTracks.Any(x => x.Artist?.Artist?.Value == trackArtist &&
|
||||
x.Release?.Release?.Value != trackRelease))
|
||||
{
|
||||
shuffledTracks.Remove(track);
|
||||
var insertAt = shuffledTracks.Count() - 1;
|
||||
foreach (var st in shuffledTracks)
|
||||
{
|
||||
if (st?.Artist?.Artist?.Value != track?.Artist?.Artist?.Value &&
|
||||
st?.Release?.Release?.Value != track?.Release?.Release?.Value)
|
||||
{
|
||||
break;
|
||||
}
|
||||
insertAt--;
|
||||
}
|
||||
shuffledTracks.Insert(insertAt, track);
|
||||
lastTrack = track;
|
||||
continue;
|
||||
shuffledTracks.Add(track);
|
||||
}
|
||||
else
|
||||
{
|
||||
skippedTracks.Add(track);
|
||||
}
|
||||
lastTrack = track;
|
||||
}
|
||||
return shuffledTracks;
|
||||
var result = new List<TrackList>(shuffledTracks);
|
||||
while (skippedTracks.ToList().Any())
|
||||
{
|
||||
var st = skippedTracks.First();
|
||||
var trackArtist = st.Artist?.Artist?.Value;
|
||||
var insertAt = AllIndexesOfArtist(result, trackArtist).Last() + 2;
|
||||
if(insertAt < result.Count() - 1)
|
||||
{
|
||||
result.Insert(insertAt, st);
|
||||
skippedTracks.Remove(st);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -306,31 +306,33 @@ namespace Roadie.Api.Services
|
|||
favoriteTrackIds = new int[0].AsQueryable();
|
||||
request.FilterFavoriteOnly = false;
|
||||
}
|
||||
randomTrackIds = TrackList.Shuffle((from t in DbContext.Tracks
|
||||
join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
|
||||
join r in DbContext.Releases on rm.ReleaseId equals r.Id
|
||||
join a in DbContext.Artists on r.ArtistId equals a.Id
|
||||
where !request.FilterRatedOnly || request.FilterRatedOnly && t.Rating > 0
|
||||
where !dislikedArtistIds.Contains(r.ArtistId)
|
||||
where !dislikedArtistIds.Contains(t.ArtistId ?? 0)
|
||||
where !dislikedReleaseIds.Contains(r.Id)
|
||||
where !dislikedTrackIds.Contains(t.Id)
|
||||
where favoritedTrackIds == null || favoritedTrackIds.Contains(t.Id)
|
||||
where t.Hash != null
|
||||
select new TrackList
|
||||
{
|
||||
DatabaseId = t.Id,
|
||||
Artist = new ArtistList
|
||||
{
|
||||
Artist = new DataToken { Value = a.RoadieId.ToString(), Text = a.Name }
|
||||
},
|
||||
Release = new ReleaseList
|
||||
{
|
||||
Release = new DataToken { Value = r.RoadieId.ToString(), Text = r.Title }
|
||||
}
|
||||
})
|
||||
.OrderBy(x => x.RandomSortId)
|
||||
.Take(randomLimit))
|
||||
randomTrackIds = (from t in DbContext.Tracks
|
||||
join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
|
||||
join r in DbContext.Releases on rm.ReleaseId equals r.Id
|
||||
join a in DbContext.Artists on r.ArtistId equals a.Id
|
||||
where !request.FilterRatedOnly || request.FilterRatedOnly && t.Rating > 0
|
||||
where !dislikedArtistIds.Contains(r.ArtistId)
|
||||
where !dislikedArtistIds.Contains(t.ArtistId ?? 0)
|
||||
where !dislikedReleaseIds.Contains(r.Id)
|
||||
where !dislikedTrackIds.Contains(t.Id)
|
||||
where favoritedTrackIds == null || favoritedTrackIds.Contains(t.Id)
|
||||
where t.Hash != null
|
||||
select new TrackList
|
||||
{
|
||||
DatabaseId = t.Id,
|
||||
Artist = new ArtistList
|
||||
{
|
||||
Artist = new DataToken { Value = a.RoadieId.ToString(), Text = a.Name }
|
||||
},
|
||||
Release = new ReleaseList
|
||||
{
|
||||
Release = new DataToken { Value = r.RoadieId.ToString(), Text = r.Title }
|
||||
}
|
||||
})
|
||||
.OrderBy(x => x.Artist.RandomSortId)
|
||||
.ThenBy(x => x.RandomSortId)
|
||||
.ThenBy(x => x.RandomSortId)
|
||||
.Take(randomLimit)
|
||||
.Select(x => x.DatabaseId)
|
||||
.ToArray();
|
||||
}
|
||||
|
@ -598,7 +600,7 @@ namespace Roadie.Api.Services
|
|||
|
||||
if(doRandomize ?? false)
|
||||
{
|
||||
rows = result.ToArray();
|
||||
rows = TrackList.Shuffle(result).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"Roadie.Api": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
||||
},
|
||||
"applicationUrl": "http://localhost:5123/"
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue