поправителен изпит - 3 зад.
имате ли идея как да сортирам финалния вложен речник?
using System;
using System.Collections.Generic;
using System.Linq;
namespace exampr
{
class Program
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
Dictionary<string,Dictionary<string,List<string>>> listOfPianoProducers = new Dictionary<string,Dictionary<string,List<string>>>();
for (int i = 0; i < n; i++)
{
string[] input = Console.ReadLine().Split('|').ToArray();
string key = input[2];
string composer = input[1];
string piece = input[0];
List<string> pieces = new List<string>();
pieces.Add(piece);
Dictionary<string, List<string>> autthorPiece = new Dictionary<string, List<string>>();
autthorPiece.Add(composer, pieces);
if (listOfPianoProducers.ContainsKey(key))
{
if (listOfPianoProducers[key].ContainsKey(composer))
{
if(!listOfPianoProducers[key][composer].Contains(piece))
{
listOfPianoProducers[key][composer].Add(piece);
}
}
else
{
listOfPianoProducers[key].Add(composer,pieces);
}
}
else
{
listOfPianoProducers.Add(key,autthorPiece);
}
}
Console.WriteLine(listOfPianoProducers.Count);
while (true)
{
string input = Console.ReadLine();
if(input == "Stop")
{
break;
}
string[] command = input.Split('|').ToArray();
if (command[0] == "Add")
{
string piece = command[1];
string composer = command[2];
string key = command[3];
Console.WriteLine(1);
bool count = false;
foreach(var item in listOfPianoProducers)
{
foreach(var name in item.Value)
{
if (name.Value.Contains(piece))
{
Console.WriteLine($"{piece} is already in the collection!");
count = true;
}
}
}
if (!count)
{
if (listOfPianoProducers.ContainsKey(key))
{
if (listOfPianoProducers[key].ContainsKey(composer))
{
listOfPianoProducers[key][composer].Add(piece);
}
else
{
listOfPianoProducers[key].Add(composer, new List<string> { piece });
}
}
else
{
List<string> pieces = new List<string>();
pieces.Add(piece);
Dictionary<string, List<string>> autthorPiece = new Dictionary<string, List<string>>();
autthorPiece.Add(composer, pieces);
listOfPianoProducers.Add(key, autthorPiece);
}
Console.WriteLine($"{piece} by {composer} in {key} added to the collection!");
}
}else if(command[0] == "Remove")
{
string piece = command[1];
bool count = false;
foreach (var item in listOfPianoProducers)
{
foreach (var name in item.Value)
{
if (name.Value.Contains(piece))
{
name.Value.Remove(piece);
count = true;
}
}
}
if (count)
{
Console.WriteLine($"Successfully removed {piece}!");
}
else
{
Console.WriteLine($"Invalid operation! {piece} does not exist in the collection.");
}
}
else
{
string piece = command[1];
string key = command[2];
string oldKey = "";
string oldComposer = "";
bool count = false;
foreach (var item in listOfPianoProducers)
{
foreach (var name in item.Value)
{
if (name.Value.Contains(piece))
{
name.Value.Remove(piece);
count = true;
oldKey = item.Key;
oldComposer = name.Key;
}
}
}
if (count)
{
//listOfPianoProducers.Remove(oldKey);
Dictionary<string, List<string>> autthorPiece = new Dictionary<string, List<string>>();
autthorPiece.Add(oldComposer, new List<string> { piece });
listOfPianoProducers.Add(key,autthorPiece);
Console.WriteLine($"Changed the key of {piece} to {key}!");
}
else
{
Console.WriteLine($"Invalid operation! {piece} does not exist in the collection.");
}
}
}
Console.WriteLine(listOfPianoProducers.Count);
foreach(var item in listOfPianoProducers)
{
foreach(var item1 in item.Value)
{
foreach (var item2 in item1.Value)
{
Console.WriteLine($"{item2} -> Composer: {item1.Key}, Key: {item.Key}");
}
}
}
}
}
}
не става с тази сортировка ,това което трябва да се сортира първо се намира в края на речника в листовете
До колкото си спомням в задача искаха да се подреди по Име на произведението и после по Име на композитора. При твоята структура на речника се получава малко объркване. Трябва да си структурираш данните по следния начин;
1 - Име на произведението (Piece), което ще играе роля на Key за Dictionary-то. (което е стринг както си го написал в кода))
За Value към този ключ, слагаш или речник или масив[2], лично смятам, че вложения речник само усложнява нещата. На упражненията ни го показаха за да видим как работи но според мен в подобна задача е ненужно.
2 - Тук според мен си слагаш един масив[2] - {ключ, автор }
Тогава сортировката би изглеждала така
var ordered = listOfPianoProducers.Orderby(x => x.Key).Thenby(x => x.Value[1]);
Тоест първо подреждаш по име на произведението в случая Key за речника
После по Value[1], дефакто ти е името на Композитора (индекс 1 на масива, който е Value)
А иначе както е писал nickwork, тия задачи са супер лесни с класове и обекти, след час два ще се опитем да ти изпратя такова решение.
Абсолютно съм съгласен с колегата - няма нужда да си усложняваш живота с вложен речник. Вложен масив или лист върши идеална работа за тази задача, а и сортировката му е много по- лесна.
Това е решение с класове, до толкова доколкото ги схващам че и аз съм на Фундаменталс още:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ExamTask3
{
class Program
{
static void Main(string[] args)
{
int numberOfInputs = int.Parse(Console.ReadLine());
List<Piece> musicList = new List<Piece>();
for (int i = 0; i < numberOfInputs; i++)
{
string[] input = Console.ReadLine().Split("|").ToArray();
Piece currentPiece = new Piece(input[0], input[1], input[2]);
musicList.Add(currentPiece);
}
string inputCommand = Console.ReadLine();
while (inputCommand != "Stop")
{
string[] command = inputCommand.Split("|").ToArray();
Piece currentPiece = musicList.FirstOrDefault(x => x.Name == command[1]);
switch (command[0])
{
case "Add":
{
if (!musicList.Contains(currentPiece))
{
Piece pieceToAdd = new Piece(command[1], command[2], command[3]);
Console.WriteLine($"{pieceToAdd.Name} by {pieceToAdd.Composer} in {pieceToAdd.Key} added to the collection");
musicList.Add(pieceToAdd);
}
else
{
Console.WriteLine($"{currentPiece.Name} is already in the collection");
}
break;
}
case "Remove":
{
if (musicList.Contains(currentPiece))
{
musicList.Remove(currentPiece);
}
else
{
Console.WriteLine($"{currentPiece.Name} is not in the collection");
}
break;
}
case "ChangeKey":
{
if (musicList.Contains(currentPiece))
{
currentPiece.ChangeKey(command[3]);
}
else
{
Console.WriteLine($"{currentPiece.Name} is not in the collection");
}
break;
}
}
inputCommand = Console.ReadLine();
}
var ordered = musicList.OrderBy(x => x.Name).ThenBy(x => x.Composer);
foreach (var piece in ordered)
{
piece.PieceToString();
}
}
}
public class Piece
{
public string Name { get; set; }
public string Composer { get; set; }
public string Key { get; set; }
public Piece(string name, string author, string key)
{
this.Name = name;
this.Composer = author;
this.Key = key;
}
public void ChangeKey(string newKey)
{
this.Key = newKey;
}
public void PieceToString()
{
Console.WriteLine($"{this.Name} -> Composer:{this.Composer}:{this.Key}");
}
}
}
Кода е доста по четим и лесен за редакция, защото класа и методите му са в отделни "кодове"