Letting New Values in LINQ
Letting New Values in LINQ
Letting a Variable
Introduction
We saw that you can get the result of a LINQ statement from the select section. In reality, the select statement simply indicates that the result is ready and it hands it to the other parts of the program. Instead of getting the result directly from the select statement, you can first store it in a local LINQ variable. This allows you to treat the result as a variable that you can then manipulate before getting the final result.
Letting a Local Variable
To allow you to declare a local variable in the LINQ statement, the LINQ provides an operator named let. You must use it before the select statement to hold the result and you must initialize the variable. Normally, the variable can hold a constant value. At the end of the query, you can select that let variable and later use it as the returned value. Here is an example:
namespace Numerotation
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Load(object sender, EventArgs e)
{
var loan = new double[] { 1250d, 12.05d, 36d };
var number = from n
in loan
let principal = 2465D
select principal;
foreach (var nbr in number)
{
txtPrincipal.Text = nbr.ToString();
}
}
}
}
This would produce:
Letting a Value from a List
If your query is based on an array, you can assign a value of that array to the let variable. You can get the value based on the index that represents its position in the array. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
var loan = new double[] { 1250d, 12.05d, 36d };
var number = from n
in loan
let principal = loan[0]
select principal;
foreach (var nbr in number)
{
txtPrincipal.Text = nbr.ToString();
}
}
This would produce:
Letting an Expression
Instead of a constant value, you can create an expression and assign it to the let variable. The expression can be made of constant values. You can also use the members of the array by accessing each based on its index. Here is an example:
namespace Numerotation
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Load(object sender, EventArgs e)
{
var loan = new double[] { 800, 9, 4 }; // 1250d, 12.05d, 36d };
// Amount Paid = Principal(1 + Interest Rate * Periods)
// = Principal{1 + [(Interest Rate / 100) * (Periods in Months / 12)]}
var number = from n
in loan
let amtPaid = loan[0] * (1 + (loan[1] / 100 * loan[2]/12))
select amtPaid;
foreach (var nbr in number)
{
txtAmountPaid.Text = nbr.ToString();
}
}
}
}
This would produce:
Letting Many Values
You can declare more than one let variable. When you exit the statement, you can select only one of the variables and use it outside of the query. Here is an example:
namespace Numerotation { public partial class Exercise : Form { public Exercise() { InitializeComponent(); } private void Exercise_Load(object sender, EventArgs e) { var loan = new double[] { 1250d, 12.05d, 36d }; // Future Value = Principal(1 + Interest Rate * Periods) // = Principal{1 + [(Interest Rate / 100) * (Periods in Months / 12)]} // Interest Paid = Future Value - Principal var number = from n in loan let futurevalue = loan[0] * (1 + (loan[1] / 100 * loan[2] / 12)) let interestPaid = futurevalue - loan[0] select interestPaid; foreach (var nbr in number) { txtInterestPaid.Text = nbr.ToString("F"); } } } }
This would produce:
You can include a where condition in your let variable if you want to check a condition. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
var loan = new double[] { 1250d, 12.05d, 36d };
var number = from n
in loan
where loan[0] > 1000
let futurevalue = loan[0] * (1 + (loan[1] / 100 * loan[2] / 12))
select futurevalue;
foreach (var nbr in number)
{
txtFutureValue.Text = nbr.ToString("F");
}
}
The where statement can be included before or after the let statement and you would get the same result:
private void Exercise_Load(object sender, EventArgs e)
{
var loan = new double[] { 1250d, 12.05d, 36d };
var number = from n
in loan
let futurevalue = loan[0] * (1 + (loan[1] / 100 * loan[2] / 12))
where loan[0] > 1000
select futurevalue;
foreach (var nbr in number)
{
txtFutureValue.Text = nbr.ToString("F");
}
}
Letting a Sub-List
In the LINQ, the let operator is used to declare a local variable in a query statement. To specify the value of the variable, you can create an expression that combines the members of a class and assign that expression to the let variable. To end your query, select that variable. Outside the query, access that variable from the var variable of the foreach loop. Here is an example:
namespace Numerotation
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Load(object sender, EventArgs e)
{
Video[] lstVideos = new Video[]
{
new Video(274880, "Platoon", "Oliver Stone", "R", 1986, false),
new Video(792075, "Two for the Money", "D.J. Caruso", "R", 2008, true),
new Video(283748, "Cousin Vinny (My)", "Jonathan Lynn", "R", 1992, false),
new Video(593940, "Natural Born Killers", "Oliver Stone", "R", 1994, true),
new Video(900245, "Her Alibi", "Bruce Beresford", "PG-13", 1998, false),
new Video(773022, "Distinguished Gentleman (The)", "Jonathan Lynn", "R", 1992, false),
new Video(961973, "Wall Street", "Oliver Stone", "R", 2000, false),
new Video(180358, "Memoirs of a Geisha", "Rob Marshall", "PG-13", 2006, true)
};
var vdos = from videos
in lstVideos
let video = "\"" + videos.Title + "\" directed by " + videos.Director + ", released in " + videos.YearReleased.ToString()
select video;
foreach (var vdo in vdos)
cbxVideos.Items.Add(vdo);
}
}
readonly record struct Video
{
public int ShelfNumber { get; init; }
public string Title { get; init; }
public string Director { get; init; }
public string Rating { get; init; }
public int YearReleased { get; init; }
public bool WideScreen { get; init; }
public Video(int id, string title, string dir,
string rating, int year, bool hd = false)
{
ShelfNumber = id;
Title = title;
Director = dir;
Rating = rating;
YearReleased = year;
WideScreen = hd;
}
}
}
This would produce:
If you need a condition, add a where statement before or after the let expression. Here is an example:
var vdos = from videos
in lstVideos
where videos.Director == "Oliver Stone"
let video = "\"" + videos.Title + "\" directed by " + videos.Director + ", released in " + videos.YearReleased.ToString()
select video;
Of course, you can order the list and/or use a conjunction or disjunction.
Letting New Values
Declaring a New local Variable
We mentioned that we could declare one or more let variables in a query but we could get only one of those variables out of the query. To let you get more that one variable outside of the query, the LINQ provides an operator name new. It must follow the select keyword in the following formula:
var SubListName = from ValueHolder in List select new { };
As you can see, to use the new operator, after the select keyword, type new followed by an opening and a closing curly brackets, "{" and "}" . Inside the brackets, declare any variable of your choice and assign it the value you want. The value can be any constant you want. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
var numbers = new double[] { 1250d, 12.05d, 36d };
var number = from n
in numbers
select new
{
something = 6500
};
}
If you declare more than one variable, separate them with commas. Here are examples:
private void Exercise_Load(object sender, EventArgs e)
{
var numbers = new double[] { 1250d, 12.05d, 36d };
var number = from n
in numbers
select new
{
something = 6500, another 4.006, more 5
};
}
Remember that you can declare each variable on its own line to make the code easier to read.
If you are using the values from an array, you can locate a value by its index and assign it to the desired local variable. Here are examples:
var number = from n
in numbers
select new
{
Principal = numbers[0],
InterestRate = numbers[1],
Periods = numbers[2]
};
Either way, to access a new variable outside the query, use a foreach loop to get a contextual variable. In the body of foreach, access each new variable using the period operator. Here are examples:
namespace Numerotation { public partial class Exercise : Form { public Exercise() { InitializeComponent(); } private void Exercise_Load(object sender, EventArgs e) { var numbers = new double[] { 6500d, 11.65d, 48u }; var number = from n in numbers select new { Principal = numbers[0], InterestRate = numbers[1], Periods = numbers[2] }; foreach (var member in number) { txtPrincipal.Text = member.Principal.ToString(); txtInterestRate.Text = member.InterestRate.ToString(); txtPeriods.Text = member.Periods.ToString(); } } } }
Instead of a constant or a member of an array, a new variable can be assigned an expression. The expression can be made of constants, the members of an array, or a combination of constants and members of the array. Here are examples:
namespace Numerotation
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void Exercise_Load(object sender, EventArgs e)
{
var numbers = new double[] { 6500d, 11.65d, 48u };
var number = from n
in numbers
select new
{
Principal = numbers[0],
InterestRate = numbers[1],
Periods = numbers[2],
FutureValue = numbers[0] * (1 + (numbers[1] / 100 * numbers[2] / 12)),
InterestPaid = (numbers[0] * (1 + (numbers[1] / 100 * numbers[2] / 12))) - numbers[0],
};
foreach (var member in number)
{
txtPrincipal.Text = member.Principal.ToString();
txtInterestRate.Text = member.InterestRate.ToString();
txtPeriods.Text = member.Periods.ToString();
txtFutureValue.Text = member.FutureValue.ToString("F");
txtInterestPaid.Text = member.InterestPaid.ToString("F");
}
}
}
}
This would produce:
If necessary, you can include a where statement to check a condition. The where statement must be written before the select new section. Here is ab example:
private void Exercise_Load(object sender, EventArgs e)
{
var numbers = new double[] { 6500d, 11.65d, 48u };
var number = from n
in numbers
where numbers[0] > 5000
select new
{
Principal = numbers[0],
InterestRate = numbers[1],
Periods = numbers[2],
Futurevalue = numbers[0] * (1 + (numbers[1] / 100 * numbers[2] / 12)),
InterestPaid = (numbers[0] * (1 + (numbers[1] / 100 * numbers[2] / 12))) - numbers[0]
};
foreach (var member in number)
{
txtPrincipal.Text = member.Principal.ToString();
txtInterestRate.Text = member.InterestRate.ToString();
txtPeriods.Text = member.Periods.ToString();
txtFutureValue.Text = member.Futurevalue.ToString("F");
txtInterestPaid.Text = member.InterestPaid.ToString("F");
}
}
Creating a New Class
As we have seen above, if you query a list whose records are based on a class, you can access the members (properties and methods) of the class both in the query and in the foreach loop. As an alternative, the LINQ allows you to declare various variables in the query and access those variables in the foreach loop. To declare such variables, start with select new followed by "{" and "}":
var SubListName = from ValueHolder in List select new { ValueHolder.ClassMember1 = Value1 ValueHolder.ClassMember1 = Value2 ValueHolder.ClassMember_n = Value_n };
Inside the curly brackets, declare each variable and assign it the desired value. The value can be a member of the class. Here is an example:
var vdos = from videos
in lstVideos
select new
{
ReferenceCode = videos.ShelfNumber
};
Actually, the variable can hold the same name as a member of the class. In the same way, you can declare as many variables as you want and assign the desired class members to them. Separate the declarations with commas. Outside the query, to access a new variable, qualify it with a period operator applied to the foreach variable. Here are examples:
var vdos = from videos in lstVideos select new { ReferenceCode = videos.ShelfNumber, Name = videos.Title, Director = videos.Director, Viewership = videos.Rating, CopyrightYear = videos.YearReleased, WideScreen = videos.WideScreen, }; foreach (var vdo in vdos) { ListViewItem lviCollection = new ListViewItem(vdo.ReferenceCode.ToString()); lviCollection.SubItems.Add(vdo.Name); lviCollection.SubItems.Add(vdo.Director); lviCollection.SubItems.Add(vdo.Viewership); lviCollection.SubItems.Add(vdo.CopyrightYear.ToString()); lviCollection.SubItems.Add(vdo.WideScreen.ToString()); lvwCollection.Items.Add(lviCollection); }
This would produce:
Instead of one value, the value of a new variable can be an expression that is a combination of values (constants and/or class members). Here are examples:
namespace Numerotation { public partial class Exercise : Form { public Exercise() { InitializeComponent(); } private void Exercise_Load(object sender, EventArgs e) { Video[] lstVideos = new Video[] { new Video(274880, "Platoon", "Oliver Stone", "R", 1986, false), new Video(792075, "Two for the Money", "D.J. Caruso", "R", 2008, true), new Video(283748, "Cousin Vinny (My)", "Jonathan Lynn", "R", 1992, false), new Video(593940, "Natural Born Killers", "Oliver Stone", "R", 1994, true), new Video(900245, "Her Alibi", "Bruce Beresford", "PG-13", 1998, false), new Video(773022, "Distinguished Gentleman (The)", "Jonathan Lynn", "R", 1992, false), new Video(961973, "Wall Street", "Oliver Stone", "R", 2000, false), new Video(180358, "Memoirs of a Geisha", "Rob Marshall", "PG-13", 2006, true) }; var vdos = from videos in lstVideos select new { ReferenceCode = videos.ShelfNumber, Description = videos.Title + " (" + videos.YearReleased + ") directed by " + videos.Director, Rating = videos.Rating, WideScreen = videos.WideScreen, }; foreach (var vdo in vdos) { ListViewItem lviVideo = new ListViewItem(vdo.ReferenceCode.ToString()); lviVideo.SubItems.Add(vdo.Description); lviVideo.SubItems.Add(vdo.Rating.ToString()); lviVideo.SubItems.Add(vdo.WideScreen.ToString()); lvwVideos.Items.Add(lviVideo); } } } readonly record struct Video { internal int ShelfNumber { get; init; } internal string Title { get; init; } internal string Director { get; init; } internal string Rating { get; init; } internal int YearReleased { get; init; } internal bool WideScreen { get; init; } public Video(int id, string title, string dir, string rating, int year, bool hd = false) { ShelfNumber = id; Title = title; Director = dir; Rating = rating; YearReleased = year; WideScreen = hd; } } }
This would produce:
|
|||
Previous | Copyright © 2008-2023, FunctionX, Inc. | Wednesday 15 September 2021 | Next |
|