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.