How do I store elements in a list in ascending order that come from two other list C#?










2















The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.



This is how the items are being displayed



This is the code that is adding the items to this list and is creating the problem



List<Account> accounts = new List<Account>();

accounts.AddRange(caccounts);
accounts.AddRange(saccounts);

foreach (Account account in accounts)

List<Transaction> transactions = account.closeMonth();

allTransactions.AddRange(transactions);



This code shows the list I am adding saccounts and caccounts to



List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();


This is code that I have in my checking class and savings class that override close month in the abstract account class



public override List<Transaction> closeMonth()

var transactions = new List<Transaction>();

var endString = new Transaction();

string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());

endString.EndOfMonth = reportString;
transactions.Add(endString);

return transactions;



This is the property for the AccountID and i have this in the checking and savings class



class SavingsAccount : Account

public override int AccountID get; set;



When the account is originally created this is the code that assigns the AccountID



if (checkingRadioButton1.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)

AccountID = _nextIndex,
Student = isStudent
);

else if (savingsRadioButton2.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)

AccountID = _nextIndex,
Senior = isSenior
);










share|improve this question



















  • 1





    I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

    – Josef Biehler
    Nov 13 '18 at 22:50











  • @Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

    – Demond
    Nov 13 '18 at 23:06











  • FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

    – Rufus L
    Nov 14 '18 at 0:12







  • 1





    Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

    – Rufus L
    Nov 14 '18 at 0:16
















2















The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.



This is how the items are being displayed



This is the code that is adding the items to this list and is creating the problem



List<Account> accounts = new List<Account>();

accounts.AddRange(caccounts);
accounts.AddRange(saccounts);

foreach (Account account in accounts)

List<Transaction> transactions = account.closeMonth();

allTransactions.AddRange(transactions);



This code shows the list I am adding saccounts and caccounts to



List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();


This is code that I have in my checking class and savings class that override close month in the abstract account class



public override List<Transaction> closeMonth()

var transactions = new List<Transaction>();

var endString = new Transaction();

string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());

endString.EndOfMonth = reportString;
transactions.Add(endString);

return transactions;



This is the property for the AccountID and i have this in the checking and savings class



class SavingsAccount : Account

public override int AccountID get; set;



When the account is originally created this is the code that assigns the AccountID



if (checkingRadioButton1.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)

AccountID = _nextIndex,
Student = isStudent
);

else if (savingsRadioButton2.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)

AccountID = _nextIndex,
Senior = isSenior
);










share|improve this question



















  • 1





    I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

    – Josef Biehler
    Nov 13 '18 at 22:50











  • @Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

    – Demond
    Nov 13 '18 at 23:06











  • FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

    – Rufus L
    Nov 14 '18 at 0:12







  • 1





    Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

    – Rufus L
    Nov 14 '18 at 0:16














2












2








2








The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.



This is how the items are being displayed



This is the code that is adding the items to this list and is creating the problem



List<Account> accounts = new List<Account>();

accounts.AddRange(caccounts);
accounts.AddRange(saccounts);

foreach (Account account in accounts)

List<Transaction> transactions = account.closeMonth();

allTransactions.AddRange(transactions);



This code shows the list I am adding saccounts and caccounts to



List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();


This is code that I have in my checking class and savings class that override close month in the abstract account class



public override List<Transaction> closeMonth()

var transactions = new List<Transaction>();

var endString = new Transaction();

string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());

endString.EndOfMonth = reportString;
transactions.Add(endString);

return transactions;



This is the property for the AccountID and i have this in the checking and savings class



class SavingsAccount : Account

public override int AccountID get; set;



When the account is originally created this is the code that assigns the AccountID



if (checkingRadioButton1.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)

AccountID = _nextIndex,
Student = isStudent
);

else if (savingsRadioButton2.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)

AccountID = _nextIndex,
Senior = isSenior
);










share|improve this question
















The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.



This is how the items are being displayed



This is the code that is adding the items to this list and is creating the problem



List<Account> accounts = new List<Account>();

accounts.AddRange(caccounts);
accounts.AddRange(saccounts);

foreach (Account account in accounts)

List<Transaction> transactions = account.closeMonth();

allTransactions.AddRange(transactions);



This code shows the list I am adding saccounts and caccounts to



List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();


This is code that I have in my checking class and savings class that override close month in the abstract account class



public override List<Transaction> closeMonth()

var transactions = new List<Transaction>();

var endString = new Transaction();

string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());

endString.EndOfMonth = reportString;
transactions.Add(endString);

return transactions;



This is the property for the AccountID and i have this in the checking and savings class



class SavingsAccount : Account

public override int AccountID get; set;



When the account is originally created this is the code that assigns the AccountID



if (checkingRadioButton1.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)

AccountID = _nextIndex,
Student = isStudent
);

else if (savingsRadioButton2.Checked == true)

_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)

AccountID = _nextIndex,
Senior = isSenior
);







c#






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 0:09









Rufus L

17.7k31531




17.7k31531










asked Nov 13 '18 at 22:40









DemondDemond

545




545







  • 1





    I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

    – Josef Biehler
    Nov 13 '18 at 22:50











  • @Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

    – Demond
    Nov 13 '18 at 23:06











  • FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

    – Rufus L
    Nov 14 '18 at 0:12







  • 1





    Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

    – Rufus L
    Nov 14 '18 at 0:16













  • 1





    I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

    – Josef Biehler
    Nov 13 '18 at 22:50











  • @Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

    – Demond
    Nov 13 '18 at 23:06











  • FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

    – Rufus L
    Nov 14 '18 at 0:12







  • 1





    Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

    – Rufus L
    Nov 14 '18 at 0:16








1




1





I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

– Josef Biehler
Nov 13 '18 at 22:50





I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an order by

– Josef Biehler
Nov 13 '18 at 22:50













@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

– Demond
Nov 13 '18 at 23:06





@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?

– Demond
Nov 13 '18 at 23:06













FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

– Rufus L
Nov 14 '18 at 0:12






FYI, your closeMonth() method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";

– Rufus L
Nov 14 '18 at 0:12





1




1





Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

– Rufus L
Nov 14 '18 at 0:16






Why do you override AccountID (i.e. why is Account abstract)? Why not just use the base class? For that matter, how are the CheckingAccount and SavingsAccount class different from each other, or from the Account base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.

– Rufus L
Nov 14 '18 at 0:16













3 Answers
3






active

oldest

votes


















2














You could use OrderBy on the collection.



var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();


Of course you would need to have that CreateDate or whatever property you want ordered by in your object.






share|improve this answer

























  • I have a property for AccountId so are you stating i can do an Order By using it?

    – Demond
    Nov 13 '18 at 23:08











  • Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

    – NoSaidTheCompiler
    Nov 13 '18 at 23:10












  • Wonderful. This worked.

    – Demond
    Nov 14 '18 at 17:52


















1














Instead of using this code to merge accounts into one list



 List<Account> accounts = new List<Account>();

accounts.AddRange(caccounts);
accounts.AddRange(saccounts);

foreach (Account account in accounts)

List<Transaction> transactions = account.closeMonth();

allTransactions.AddRange(transactions);



you can use this code



List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)

if(saccountsAdded == saccounts.Count)

accounts[i] = caccounts[caccountsAdded++];
continue;

if (caccountsAdded == caccounts.Count)

accounts[i] = saccounts[saccountsAdded++];
continue;

if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)

accounts[i] = caccounts[caccountsAdded ++];


else

accounts[i] = saccounts[saccountsAdded ++];





In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated






share|improve this answer
































    1














    The short answer is that you can order your Transactions by the AccountID using the System.Linq extension method OrderBy (along with a .SelectMany method call to flatten each account's transaction list) before you output them:



    List<Transaction> transactions = accounts
    .OrderBy(a => a.AccountID)
    .SelectMany(a => a.closeMonth())
    .ToList();



    Other thoughts



    As I was answering your question, I couldn't figure out why Account was abstract, or why there was a separate class for CheckingAccount and SavingsAccount, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.



    With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.



    Accounts



    To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank that creates the accounts, and the class could have a List<Rule> AccountRules that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).



    But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl or a Deposit (or an Interest accruement).



    Transactions



    Also, the closeMonth() method seemed really strange to me. It returns a List<Transaction> that contains a single item. Instead, I think an Account should have a List<Transaction> that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType property).



    To simplify adding a new transaction to the list, I added a private AddTransaction method that takes in a Transaction.Type and a description of the transaction. It then creates the Transaction and adds it to the list. Also notice that the Transaction class automatically adds the current DateTime as a Timestamp, so there's no need to worry about that on the client side.



    Code



    To prevent race conditions where Deposit and Withdrawl are called at the same time from different threads, I added some lock() blocks around any code that accessed Balance.



    I also added an override to the ToString method on the Transaction class so that it was easier to output the details of each transaction.



    Another item of interest is that you can format a decimal as currency by using the C format string (i.e. if you have decimal balance = 5M; you can do balance.ToString("C") or "balance:C" and the string result will be "$5.00" in the U.S. or "£5.00" in England).



    So the classes might then look something like the following:



    public class Transaction

    public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
    public Type TransactionType get;
    public string Description get;
    public DateTime Timestamp get;

    public Transaction(Type transactionType, string description)

    TransactionType = transactionType;
    Description = description;
    Timestamp = DateTime.Now;


    public override string ToString()

    return $"Timestamp: TransactionType - Description";



    public class Account

    public enum Type Checking, Savings
    public Type AccountType get;
    public int Id get;
    public List<Transaction> Transactions get; private set;

    private static readonly object IdLock = new object();
    private static int _lastAccountId;

    private readonly object balanceLock = new object();
    private decimal balance;

    public Account(decimal initialDeposit, Type accountType)

    if (initialDeposit < 0)

    throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");


    AccountType = accountType;
    balance = initialDeposit;

    lock (IdLock)

    Id = ++_lastAccountId;


    AddTransaction(Transaction.Type.Open,
    $"AccountType account Id Id created with a deposit of: balance:C.");


    public void Deposit(decimal amount)

    if (amount < 0)

    throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");


    lock (balanceLock)

    balance += amount;
    AddTransaction(Transaction.Type.Deposit,
    $"amount was deposited. New balance: balance:C.");



    public void Withdraw(decimal amount)

    if (amount < 0)

    throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");


    if (amount > balance)

    throw new ArgumentOutOfRangeException(
    "Cannot withdraw more money than the account contains");


    lock (balanceLock)

    balance -= amount;
    AddTransaction(Transaction.Type.Withdrawl,
    $"amount was withdrawn. New balance: balance:C.");



    public decimal GetBalance()

    lock (balanceLock)

    AddTransaction(Transaction.Type.Inquiry,
    $"Balance inquiry made. Balance: balance:C.");
    return balance;



    private void AddTransaction(Transaction.Type transactionType, string description)

    if (Transactions == null) Transactions = new List<Transaction>();
    Transactions.Add(new Transaction(transactionType, description));




    So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:



    static void Main(string args)

    // Adding accounts in the same order as they appear on your form
    var accounts = new List<Account>

    new Account(293.05M, Account.Type.Checking),
    new Account(293.05M, Account.Type.Checking),
    new Account(300M, Account.Type.Savings),
    new Account(300M, Account.Type.Savings),
    ;

    // Sort transactions by account Id
    List<Transaction> transactions = accounts
    .OrderBy(a => a.Id)
    .SelectMany(a => a.Transactions)
    .ToList();

    // Write results to Console
    transactions.ForEach(Console.WriteLine);

    GetKeyFromUser("nDone! Press any key to exit...");



    Output



    enter image description here






    share|improve this answer























    • Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

      – Demond
      Nov 14 '18 at 17:55











    • Oh, that makes sense. :)

      – Rufus L
      Nov 14 '18 at 18:26










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290586%2fhow-do-i-store-elements-in-a-list-in-ascending-order-that-come-from-two-other-li%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    You could use OrderBy on the collection.



    var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();


    Of course you would need to have that CreateDate or whatever property you want ordered by in your object.






    share|improve this answer

























    • I have a property for AccountId so are you stating i can do an Order By using it?

      – Demond
      Nov 13 '18 at 23:08











    • Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

      – NoSaidTheCompiler
      Nov 13 '18 at 23:10












    • Wonderful. This worked.

      – Demond
      Nov 14 '18 at 17:52















    2














    You could use OrderBy on the collection.



    var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();


    Of course you would need to have that CreateDate or whatever property you want ordered by in your object.






    share|improve this answer

























    • I have a property for AccountId so are you stating i can do an Order By using it?

      – Demond
      Nov 13 '18 at 23:08











    • Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

      – NoSaidTheCompiler
      Nov 13 '18 at 23:10












    • Wonderful. This worked.

      – Demond
      Nov 14 '18 at 17:52













    2












    2








    2







    You could use OrderBy on the collection.



    var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();


    Of course you would need to have that CreateDate or whatever property you want ordered by in your object.






    share|improve this answer















    You could use OrderBy on the collection.



    var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();


    Of course you would need to have that CreateDate or whatever property you want ordered by in your object.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 13 '18 at 23:12

























    answered Nov 13 '18 at 22:52









    NoSaidTheCompilerNoSaidTheCompiler

    1,77721834




    1,77721834












    • I have a property for AccountId so are you stating i can do an Order By using it?

      – Demond
      Nov 13 '18 at 23:08











    • Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

      – NoSaidTheCompiler
      Nov 13 '18 at 23:10












    • Wonderful. This worked.

      – Demond
      Nov 14 '18 at 17:52

















    • I have a property for AccountId so are you stating i can do an Order By using it?

      – Demond
      Nov 13 '18 at 23:08











    • Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

      – NoSaidTheCompiler
      Nov 13 '18 at 23:10












    • Wonderful. This worked.

      – Demond
      Nov 14 '18 at 17:52
















    I have a property for AccountId so are you stating i can do an Order By using it?

    – Demond
    Nov 13 '18 at 23:08





    I have a property for AccountId so are you stating i can do an Order By using it?

    – Demond
    Nov 13 '18 at 23:08













    Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

    – NoSaidTheCompiler
    Nov 13 '18 at 23:10






    Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.

    – NoSaidTheCompiler
    Nov 13 '18 at 23:10














    Wonderful. This worked.

    – Demond
    Nov 14 '18 at 17:52





    Wonderful. This worked.

    – Demond
    Nov 14 '18 at 17:52













    1














    Instead of using this code to merge accounts into one list



     List<Account> accounts = new List<Account>();

    accounts.AddRange(caccounts);
    accounts.AddRange(saccounts);

    foreach (Account account in accounts)

    List<Transaction> transactions = account.closeMonth();

    allTransactions.AddRange(transactions);



    you can use this code



    List<Account> accounts = new List<Account>();
    int saccountsAdded = 0;
    int caccountsAdded = 0;
    for (int i = 0; i < saccounts.Count + caccounts.Count; i++)

    if(saccountsAdded == saccounts.Count)

    accounts[i] = caccounts[caccountsAdded++];
    continue;

    if (caccountsAdded == caccounts.Count)

    accounts[i] = saccounts[saccountsAdded++];
    continue;

    if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)

    accounts[i] = caccounts[caccountsAdded ++];


    else

    accounts[i] = saccounts[saccountsAdded ++];





    In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
    You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated






    share|improve this answer





























      1














      Instead of using this code to merge accounts into one list



       List<Account> accounts = new List<Account>();

      accounts.AddRange(caccounts);
      accounts.AddRange(saccounts);

      foreach (Account account in accounts)

      List<Transaction> transactions = account.closeMonth();

      allTransactions.AddRange(transactions);



      you can use this code



      List<Account> accounts = new List<Account>();
      int saccountsAdded = 0;
      int caccountsAdded = 0;
      for (int i = 0; i < saccounts.Count + caccounts.Count; i++)

      if(saccountsAdded == saccounts.Count)

      accounts[i] = caccounts[caccountsAdded++];
      continue;

      if (caccountsAdded == caccounts.Count)

      accounts[i] = saccounts[saccountsAdded++];
      continue;

      if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)

      accounts[i] = caccounts[caccountsAdded ++];


      else

      accounts[i] = saccounts[saccountsAdded ++];





      In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
      You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated






      share|improve this answer



























        1












        1








        1







        Instead of using this code to merge accounts into one list



         List<Account> accounts = new List<Account>();

        accounts.AddRange(caccounts);
        accounts.AddRange(saccounts);

        foreach (Account account in accounts)

        List<Transaction> transactions = account.closeMonth();

        allTransactions.AddRange(transactions);



        you can use this code



        List<Account> accounts = new List<Account>();
        int saccountsAdded = 0;
        int caccountsAdded = 0;
        for (int i = 0; i < saccounts.Count + caccounts.Count; i++)

        if(saccountsAdded == saccounts.Count)

        accounts[i] = caccounts[caccountsAdded++];
        continue;

        if (caccountsAdded == caccounts.Count)

        accounts[i] = saccounts[saccountsAdded++];
        continue;

        if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)

        accounts[i] = caccounts[caccountsAdded ++];


        else

        accounts[i] = saccounts[saccountsAdded ++];





        In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
        You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated






        share|improve this answer















        Instead of using this code to merge accounts into one list



         List<Account> accounts = new List<Account>();

        accounts.AddRange(caccounts);
        accounts.AddRange(saccounts);

        foreach (Account account in accounts)

        List<Transaction> transactions = account.closeMonth();

        allTransactions.AddRange(transactions);



        you can use this code



        List<Account> accounts = new List<Account>();
        int saccountsAdded = 0;
        int caccountsAdded = 0;
        for (int i = 0; i < saccounts.Count + caccounts.Count; i++)

        if(saccountsAdded == saccounts.Count)

        accounts[i] = caccounts[caccountsAdded++];
        continue;

        if (caccountsAdded == caccounts.Count)

        accounts[i] = saccounts[saccountsAdded++];
        continue;

        if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)

        accounts[i] = caccounts[caccountsAdded ++];


        else

        accounts[i] = saccounts[saccountsAdded ++];





        In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
        You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 13 '18 at 23:17

























        answered Nov 13 '18 at 23:08









        Dusan RadovanovicDusan Radovanovic

        437111




        437111





















            1














            The short answer is that you can order your Transactions by the AccountID using the System.Linq extension method OrderBy (along with a .SelectMany method call to flatten each account's transaction list) before you output them:



            List<Transaction> transactions = accounts
            .OrderBy(a => a.AccountID)
            .SelectMany(a => a.closeMonth())
            .ToList();



            Other thoughts



            As I was answering your question, I couldn't figure out why Account was abstract, or why there was a separate class for CheckingAccount and SavingsAccount, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.



            With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.



            Accounts



            To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank that creates the accounts, and the class could have a List<Rule> AccountRules that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).



            But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl or a Deposit (or an Interest accruement).



            Transactions



            Also, the closeMonth() method seemed really strange to me. It returns a List<Transaction> that contains a single item. Instead, I think an Account should have a List<Transaction> that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType property).



            To simplify adding a new transaction to the list, I added a private AddTransaction method that takes in a Transaction.Type and a description of the transaction. It then creates the Transaction and adds it to the list. Also notice that the Transaction class automatically adds the current DateTime as a Timestamp, so there's no need to worry about that on the client side.



            Code



            To prevent race conditions where Deposit and Withdrawl are called at the same time from different threads, I added some lock() blocks around any code that accessed Balance.



            I also added an override to the ToString method on the Transaction class so that it was easier to output the details of each transaction.



            Another item of interest is that you can format a decimal as currency by using the C format string (i.e. if you have decimal balance = 5M; you can do balance.ToString("C") or "balance:C" and the string result will be "$5.00" in the U.S. or "£5.00" in England).



            So the classes might then look something like the following:



            public class Transaction

            public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
            public Type TransactionType get;
            public string Description get;
            public DateTime Timestamp get;

            public Transaction(Type transactionType, string description)

            TransactionType = transactionType;
            Description = description;
            Timestamp = DateTime.Now;


            public override string ToString()

            return $"Timestamp: TransactionType - Description";



            public class Account

            public enum Type Checking, Savings
            public Type AccountType get;
            public int Id get;
            public List<Transaction> Transactions get; private set;

            private static readonly object IdLock = new object();
            private static int _lastAccountId;

            private readonly object balanceLock = new object();
            private decimal balance;

            public Account(decimal initialDeposit, Type accountType)

            if (initialDeposit < 0)

            throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");


            AccountType = accountType;
            balance = initialDeposit;

            lock (IdLock)

            Id = ++_lastAccountId;


            AddTransaction(Transaction.Type.Open,
            $"AccountType account Id Id created with a deposit of: balance:C.");


            public void Deposit(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");


            lock (balanceLock)

            balance += amount;
            AddTransaction(Transaction.Type.Deposit,
            $"amount was deposited. New balance: balance:C.");



            public void Withdraw(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");


            if (amount > balance)

            throw new ArgumentOutOfRangeException(
            "Cannot withdraw more money than the account contains");


            lock (balanceLock)

            balance -= amount;
            AddTransaction(Transaction.Type.Withdrawl,
            $"amount was withdrawn. New balance: balance:C.");



            public decimal GetBalance()

            lock (balanceLock)

            AddTransaction(Transaction.Type.Inquiry,
            $"Balance inquiry made. Balance: balance:C.");
            return balance;



            private void AddTransaction(Transaction.Type transactionType, string description)

            if (Transactions == null) Transactions = new List<Transaction>();
            Transactions.Add(new Transaction(transactionType, description));




            So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:



            static void Main(string args)

            // Adding accounts in the same order as they appear on your form
            var accounts = new List<Account>

            new Account(293.05M, Account.Type.Checking),
            new Account(293.05M, Account.Type.Checking),
            new Account(300M, Account.Type.Savings),
            new Account(300M, Account.Type.Savings),
            ;

            // Sort transactions by account Id
            List<Transaction> transactions = accounts
            .OrderBy(a => a.Id)
            .SelectMany(a => a.Transactions)
            .ToList();

            // Write results to Console
            transactions.ForEach(Console.WriteLine);

            GetKeyFromUser("nDone! Press any key to exit...");



            Output



            enter image description here






            share|improve this answer























            • Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

              – Demond
              Nov 14 '18 at 17:55











            • Oh, that makes sense. :)

              – Rufus L
              Nov 14 '18 at 18:26















            1














            The short answer is that you can order your Transactions by the AccountID using the System.Linq extension method OrderBy (along with a .SelectMany method call to flatten each account's transaction list) before you output them:



            List<Transaction> transactions = accounts
            .OrderBy(a => a.AccountID)
            .SelectMany(a => a.closeMonth())
            .ToList();



            Other thoughts



            As I was answering your question, I couldn't figure out why Account was abstract, or why there was a separate class for CheckingAccount and SavingsAccount, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.



            With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.



            Accounts



            To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank that creates the accounts, and the class could have a List<Rule> AccountRules that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).



            But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl or a Deposit (or an Interest accruement).



            Transactions



            Also, the closeMonth() method seemed really strange to me. It returns a List<Transaction> that contains a single item. Instead, I think an Account should have a List<Transaction> that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType property).



            To simplify adding a new transaction to the list, I added a private AddTransaction method that takes in a Transaction.Type and a description of the transaction. It then creates the Transaction and adds it to the list. Also notice that the Transaction class automatically adds the current DateTime as a Timestamp, so there's no need to worry about that on the client side.



            Code



            To prevent race conditions where Deposit and Withdrawl are called at the same time from different threads, I added some lock() blocks around any code that accessed Balance.



            I also added an override to the ToString method on the Transaction class so that it was easier to output the details of each transaction.



            Another item of interest is that you can format a decimal as currency by using the C format string (i.e. if you have decimal balance = 5M; you can do balance.ToString("C") or "balance:C" and the string result will be "$5.00" in the U.S. or "£5.00" in England).



            So the classes might then look something like the following:



            public class Transaction

            public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
            public Type TransactionType get;
            public string Description get;
            public DateTime Timestamp get;

            public Transaction(Type transactionType, string description)

            TransactionType = transactionType;
            Description = description;
            Timestamp = DateTime.Now;


            public override string ToString()

            return $"Timestamp: TransactionType - Description";



            public class Account

            public enum Type Checking, Savings
            public Type AccountType get;
            public int Id get;
            public List<Transaction> Transactions get; private set;

            private static readonly object IdLock = new object();
            private static int _lastAccountId;

            private readonly object balanceLock = new object();
            private decimal balance;

            public Account(decimal initialDeposit, Type accountType)

            if (initialDeposit < 0)

            throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");


            AccountType = accountType;
            balance = initialDeposit;

            lock (IdLock)

            Id = ++_lastAccountId;


            AddTransaction(Transaction.Type.Open,
            $"AccountType account Id Id created with a deposit of: balance:C.");


            public void Deposit(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");


            lock (balanceLock)

            balance += amount;
            AddTransaction(Transaction.Type.Deposit,
            $"amount was deposited. New balance: balance:C.");



            public void Withdraw(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");


            if (amount > balance)

            throw new ArgumentOutOfRangeException(
            "Cannot withdraw more money than the account contains");


            lock (balanceLock)

            balance -= amount;
            AddTransaction(Transaction.Type.Withdrawl,
            $"amount was withdrawn. New balance: balance:C.");



            public decimal GetBalance()

            lock (balanceLock)

            AddTransaction(Transaction.Type.Inquiry,
            $"Balance inquiry made. Balance: balance:C.");
            return balance;



            private void AddTransaction(Transaction.Type transactionType, string description)

            if (Transactions == null) Transactions = new List<Transaction>();
            Transactions.Add(new Transaction(transactionType, description));




            So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:



            static void Main(string args)

            // Adding accounts in the same order as they appear on your form
            var accounts = new List<Account>

            new Account(293.05M, Account.Type.Checking),
            new Account(293.05M, Account.Type.Checking),
            new Account(300M, Account.Type.Savings),
            new Account(300M, Account.Type.Savings),
            ;

            // Sort transactions by account Id
            List<Transaction> transactions = accounts
            .OrderBy(a => a.Id)
            .SelectMany(a => a.Transactions)
            .ToList();

            // Write results to Console
            transactions.ForEach(Console.WriteLine);

            GetKeyFromUser("nDone! Press any key to exit...");



            Output



            enter image description here






            share|improve this answer























            • Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

              – Demond
              Nov 14 '18 at 17:55











            • Oh, that makes sense. :)

              – Rufus L
              Nov 14 '18 at 18:26













            1












            1








            1







            The short answer is that you can order your Transactions by the AccountID using the System.Linq extension method OrderBy (along with a .SelectMany method call to flatten each account's transaction list) before you output them:



            List<Transaction> transactions = accounts
            .OrderBy(a => a.AccountID)
            .SelectMany(a => a.closeMonth())
            .ToList();



            Other thoughts



            As I was answering your question, I couldn't figure out why Account was abstract, or why there was a separate class for CheckingAccount and SavingsAccount, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.



            With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.



            Accounts



            To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank that creates the accounts, and the class could have a List<Rule> AccountRules that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).



            But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl or a Deposit (or an Interest accruement).



            Transactions



            Also, the closeMonth() method seemed really strange to me. It returns a List<Transaction> that contains a single item. Instead, I think an Account should have a List<Transaction> that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType property).



            To simplify adding a new transaction to the list, I added a private AddTransaction method that takes in a Transaction.Type and a description of the transaction. It then creates the Transaction and adds it to the list. Also notice that the Transaction class automatically adds the current DateTime as a Timestamp, so there's no need to worry about that on the client side.



            Code



            To prevent race conditions where Deposit and Withdrawl are called at the same time from different threads, I added some lock() blocks around any code that accessed Balance.



            I also added an override to the ToString method on the Transaction class so that it was easier to output the details of each transaction.



            Another item of interest is that you can format a decimal as currency by using the C format string (i.e. if you have decimal balance = 5M; you can do balance.ToString("C") or "balance:C" and the string result will be "$5.00" in the U.S. or "£5.00" in England).



            So the classes might then look something like the following:



            public class Transaction

            public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
            public Type TransactionType get;
            public string Description get;
            public DateTime Timestamp get;

            public Transaction(Type transactionType, string description)

            TransactionType = transactionType;
            Description = description;
            Timestamp = DateTime.Now;


            public override string ToString()

            return $"Timestamp: TransactionType - Description";



            public class Account

            public enum Type Checking, Savings
            public Type AccountType get;
            public int Id get;
            public List<Transaction> Transactions get; private set;

            private static readonly object IdLock = new object();
            private static int _lastAccountId;

            private readonly object balanceLock = new object();
            private decimal balance;

            public Account(decimal initialDeposit, Type accountType)

            if (initialDeposit < 0)

            throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");


            AccountType = accountType;
            balance = initialDeposit;

            lock (IdLock)

            Id = ++_lastAccountId;


            AddTransaction(Transaction.Type.Open,
            $"AccountType account Id Id created with a deposit of: balance:C.");


            public void Deposit(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");


            lock (balanceLock)

            balance += amount;
            AddTransaction(Transaction.Type.Deposit,
            $"amount was deposited. New balance: balance:C.");



            public void Withdraw(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");


            if (amount > balance)

            throw new ArgumentOutOfRangeException(
            "Cannot withdraw more money than the account contains");


            lock (balanceLock)

            balance -= amount;
            AddTransaction(Transaction.Type.Withdrawl,
            $"amount was withdrawn. New balance: balance:C.");



            public decimal GetBalance()

            lock (balanceLock)

            AddTransaction(Transaction.Type.Inquiry,
            $"Balance inquiry made. Balance: balance:C.");
            return balance;



            private void AddTransaction(Transaction.Type transactionType, string description)

            if (Transactions == null) Transactions = new List<Transaction>();
            Transactions.Add(new Transaction(transactionType, description));




            So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:



            static void Main(string args)

            // Adding accounts in the same order as they appear on your form
            var accounts = new List<Account>

            new Account(293.05M, Account.Type.Checking),
            new Account(293.05M, Account.Type.Checking),
            new Account(300M, Account.Type.Savings),
            new Account(300M, Account.Type.Savings),
            ;

            // Sort transactions by account Id
            List<Transaction> transactions = accounts
            .OrderBy(a => a.Id)
            .SelectMany(a => a.Transactions)
            .ToList();

            // Write results to Console
            transactions.ForEach(Console.WriteLine);

            GetKeyFromUser("nDone! Press any key to exit...");



            Output



            enter image description here






            share|improve this answer













            The short answer is that you can order your Transactions by the AccountID using the System.Linq extension method OrderBy (along with a .SelectMany method call to flatten each account's transaction list) before you output them:



            List<Transaction> transactions = accounts
            .OrderBy(a => a.AccountID)
            .SelectMany(a => a.closeMonth())
            .ToList();



            Other thoughts



            As I was answering your question, I couldn't figure out why Account was abstract, or why there was a separate class for CheckingAccount and SavingsAccount, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.



            With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.



            Accounts



            To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank that creates the accounts, and the class could have a List<Rule> AccountRules that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).



            But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl or a Deposit (or an Interest accruement).



            Transactions



            Also, the closeMonth() method seemed really strange to me. It returns a List<Transaction> that contains a single item. Instead, I think an Account should have a List<Transaction> that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType property).



            To simplify adding a new transaction to the list, I added a private AddTransaction method that takes in a Transaction.Type and a description of the transaction. It then creates the Transaction and adds it to the list. Also notice that the Transaction class automatically adds the current DateTime as a Timestamp, so there's no need to worry about that on the client side.



            Code



            To prevent race conditions where Deposit and Withdrawl are called at the same time from different threads, I added some lock() blocks around any code that accessed Balance.



            I also added an override to the ToString method on the Transaction class so that it was easier to output the details of each transaction.



            Another item of interest is that you can format a decimal as currency by using the C format string (i.e. if you have decimal balance = 5M; you can do balance.ToString("C") or "balance:C" and the string result will be "$5.00" in the U.S. or "£5.00" in England).



            So the classes might then look something like the following:



            public class Transaction

            public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
            public Type TransactionType get;
            public string Description get;
            public DateTime Timestamp get;

            public Transaction(Type transactionType, string description)

            TransactionType = transactionType;
            Description = description;
            Timestamp = DateTime.Now;


            public override string ToString()

            return $"Timestamp: TransactionType - Description";



            public class Account

            public enum Type Checking, Savings
            public Type AccountType get;
            public int Id get;
            public List<Transaction> Transactions get; private set;

            private static readonly object IdLock = new object();
            private static int _lastAccountId;

            private readonly object balanceLock = new object();
            private decimal balance;

            public Account(decimal initialDeposit, Type accountType)

            if (initialDeposit < 0)

            throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");


            AccountType = accountType;
            balance = initialDeposit;

            lock (IdLock)

            Id = ++_lastAccountId;


            AddTransaction(Transaction.Type.Open,
            $"AccountType account Id Id created with a deposit of: balance:C.");


            public void Deposit(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");


            lock (balanceLock)

            balance += amount;
            AddTransaction(Transaction.Type.Deposit,
            $"amount was deposited. New balance: balance:C.");



            public void Withdraw(decimal amount)

            if (amount < 0)

            throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");


            if (amount > balance)

            throw new ArgumentOutOfRangeException(
            "Cannot withdraw more money than the account contains");


            lock (balanceLock)

            balance -= amount;
            AddTransaction(Transaction.Type.Withdrawl,
            $"amount was withdrawn. New balance: balance:C.");



            public decimal GetBalance()

            lock (balanceLock)

            AddTransaction(Transaction.Type.Inquiry,
            $"Balance inquiry made. Balance: balance:C.");
            return balance;



            private void AddTransaction(Transaction.Type transactionType, string description)

            if (Transactions == null) Transactions = new List<Transaction>();
            Transactions.Add(new Transaction(transactionType, description));




            So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:



            static void Main(string args)

            // Adding accounts in the same order as they appear on your form
            var accounts = new List<Account>

            new Account(293.05M, Account.Type.Checking),
            new Account(293.05M, Account.Type.Checking),
            new Account(300M, Account.Type.Savings),
            new Account(300M, Account.Type.Savings),
            ;

            // Sort transactions by account Id
            List<Transaction> transactions = accounts
            .OrderBy(a => a.Id)
            .SelectMany(a => a.Transactions)
            .ToList();

            // Write results to Console
            transactions.ForEach(Console.WriteLine);

            GetKeyFromUser("nDone! Press any key to exit...");



            Output



            enter image description here







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 14 '18 at 2:11









            Rufus LRufus L

            17.7k31531




            17.7k31531












            • Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

              – Demond
              Nov 14 '18 at 17:55











            • Oh, that makes sense. :)

              – Rufus L
              Nov 14 '18 at 18:26

















            • Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

              – Demond
              Nov 14 '18 at 17:55











            • Oh, that makes sense. :)

              – Rufus L
              Nov 14 '18 at 18:26
















            Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

            – Demond
            Nov 14 '18 at 17:55





            Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.

            – Demond
            Nov 14 '18 at 17:55













            Oh, that makes sense. :)

            – Rufus L
            Nov 14 '18 at 18:26





            Oh, that makes sense. :)

            – Rufus L
            Nov 14 '18 at 18:26

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290586%2fhow-do-i-store-elements-in-a-list-in-ascending-order-that-come-from-two-other-li%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            Evgeni Malkin