Home > Enterprise >  How to form a new list from specific elements from 2 different lists?
How to form a new list from specific elements from 2 different lists?

Time:03-14

I am trying to form a new list from 2 different lists on a menuStrip button click but it either doesn't put them in "newList" list or it shows it as empty. List1 is a list for the first data file from a ".txt." file, List2 is the same, newList is for forming a new list from specific parameters from 2 lists. Suggestions?

public partial class Form1 : Form
        {
            
            List<Pieces> List1;
            List<Pieces> List2;
            List<Pieces> newList;
            Pieces piece;
    
            public Form1()
            {
                InitializeComponent();
            } 
            private void Form1_Load(object sender, EventArgs e)
            {
                enterSecondFileToolStripMenuItem.Enabled = false;
            }              
           
            private void accordingToUsersSpecificationsToolStripMenuItem_Click(object sender, EventArgs e)
            {
    
                FormAUsersList(List1,newList);
                FormAUsersList(List2,newList);
                ///newList was null error that makes no sense
                ///object refrence not set to an instance of an object 
                ///error
                finalResults.Text  = newList.ToString();
            }
           
            private void button1_Click(object sender, EventArgs e)
            {
                Close();
            }
            /// <summary>
            /// Form a list according to selected parameters by the user that we call
            /// 2 times to form a complete new list
            /// </summary>
            /// <param name="list"></param>
            /// <param name="newList"></param>
            /// <returns></returns>
            private List<Pieces> FormAUsersList(List<Pieces> list, List<Pieces> newList)
            {          
                newList = new List<Pieces>();            
                int year = Convert.ToInt32(Years.SelectedItem); /// comboBox item that signifies years
                string type = Convert.ToString(Types.SelectedItem); /// comboBox item that signifies types
                for (int i = 0; i < list.Count; i  )
                {
                    if (year <= list[i].PurchaseYear && type == list[i].Type)
                    {
                        newList.Add(list[i]);                                        
                    } 
                    
                }
               return newList;
            }
    }

CodePudding user response:

you have a bug. each time you create a new list but don't return it back.

You should remove newList = new List(); outside

private List<Pieces> FormAUsersList(List<Pieces> list, List<Pieces> newList)
 {          
     newList = new List<Pieces>();  //  remove from here
       .....
}          

and code should be

 newList = new List<Pieces>();
FormAUsersList(List1,newList);
 FormAUsersList(List2,newList); 

and IMHO you can use linq as well

var itemsToAdd=list.Where(i=> year <= i.PurchaseYear && type == i.Type);

if(itemsToAdd!=null) newList.AddRange(itemsToAdd);

CodePudding user response:

Ok, I refactored your code. I had to remove your Form code because it doesn't compile locally of course:

using Newtonsoft.Json;

namespace Pieces
{
public class Piece
{
    public class Piece
    {
        public Piece(int purchaseYear, string type)
        {
            PurchaseYear = purchaseYear;
            Type = type;
        }
        public int PurchaseYear { get; set; }
        public string Type { get; set; }

        // EDIT:
        public override string ToString()
        {
            return $"Purchased year: {PurchaseYear} Type: {Type}";
        }
    }

    public partial class Form1
    {
        List<Piece> List1 = new List<Piece> { new Piece (2022, "????"), new Piece(2021, "????") };
        List<Piece> List2 = new List<Piece> { new Piece(2020, "????"), new Piece(2019, "????") };
        List<Piece> newList;

        public Form1()
        {
            accordingToUsersSpecificationsToolStripMenuItem_Click(null, null); // Just so it compiles.
        }

        private void accordingToUsersSpecificationsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var year = 2018;
            var type = "????";

            // Create the list outside your FormUsersList() method, No need to pass newlist to it.
            newList = new List<Piece>();
            FormAUsersList(List1);
            FormAUsersList(List2);

            // Now the same with LINQ
            newList = new List<Piece>();
            FormAUsersListWithLinq(List1, year, type);
            FormAUsersListWithLinq(List2, year, type);

            // Or just LINQ
            newList = List1
                      .Union(List2)
                      .Where(x => x.PurchaseYear >= year && x.Type == type)
                      .ToList();

            // EDIT:
            newList.ForEach(x => Console.WriteLine(x));

        }

        /// <summary>
        /// Form a list according to selected parameters by the user that we call
        /// 2 times to form a complete new list
        /// </summary>
        private void FormAUsersList(List<Piece> list)
        {
            int year = 2018; // Just so it compiles
            string type = "????"; // Just so it compiles
            for (int i = 0; i < list.Count; i  )
            {
                if (year <= list[i].PurchaseYear && type == list[i].Type)
                {
                    newList.Add(list[i]);
                }
            }
        }

        private void FormAUsersListWithLinq(List<Piece> list, int year, string type)
        {
            newList.AddRange(list.Where(x => x.PurchaseYear >= year && x.Type == type));
        }
    }
}

CodePudding user response:

You should have one call to FormAUsersList that passes in List1 and List2, like so:

FormAUsersList(List1,List2);

In your code, the FormAUsersList method receives newList and immediately replaces it with a new, empty List, which doesn't make sense. The FormAUsersList should instead look more like:

private List<Pieces> FormAUsersList(List<Pieces> list1, List<Pieces> list2)
{
    List<Pieces> newList = new List<Pieces>();

    for (int i = 0; i < list1.Count; i  )
    {
        newList.Add(list1.ElementAt(i).PurchaseYear, list2.ElementAt(i).Whatever);
    }

    return newList;
}

Note that this code assumes list1 and list2 are the same length.

  • Related