我正在研究一個將修改輸入有效負載屬性的函式。有效載荷包含節點,每個節點包含特征串列。我需要洗掉一些特定的功能匹配條件,并修改每個節點視窗屬性的開始和結束時間。我已經使用傳統的嵌套 for 回圈撰寫了該函式,但很難將其轉換為 Linq 函式。任何人都知道如何將這個嵌套的 for 回圈函式轉換為 Linq 函式?
private void ApplyTransformation(InputPayload payload, int startTime = 8, int endTime = 15)
{
var nodes = payload.Nodes;
for (var i = 0; i < nodes.Count(); i)
{
var node = nodes[i];
var features = node.Features;
for (var j = 0; j < features.Count(); j)
{
var feature = features[j];
if (feature.NodeFeatureTypeID
== FeatureTypeEnum.FEATURE_A
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_B
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_C
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_D
)
{
features.RemoveAt(j);
}
}
var windows = node.Windows;
for (var k = 0; k < windows.Count(); k)
{
var window = windows[k];
if (window.NodeFunctionTypeID == FeatureTypeEnum.MM_HOURS) continue;
window.StartHour = new TimeSpan(startTime, 0, 0);
window.EndHour = new TimeSpan(endTime, 0, 0);
}
}
}
uj5u.com熱心網友回復:
對第二部分使用 linq 查詢會使事情變得更糟,最好只有一個 for 回圈
這樣的事情應該作業:
var nodes = payload.Nodes;
nodes.Features = nodes.Features.Where(f => !(
f.NodeFeatureTypeID == FeatureTypeEnum.FEATURE_A
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_B
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_C
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_D
)
);
foreach(var window in nodes.Windows)
{
if (window.NodeFunctionTypeID != FeatureTypeEnum.MM_HOURS)
{
window.StartHour = new TimeSpan(startTime, 0, 0);
window.EndHour = new TimeSpan(endTime, 0, 0);
}
}
uj5u.com熱心網友回復:
請查看下面的代碼片段以避免使用 linq 的嵌套回圈。
public class Employee
{
public string Name { get; set; }
public List<EmployeeProject> EmployeeProject { get; set; }
}
public class EmployeeProject
{
public string ProjectName { get; set; }
public string ClientName { get; set; }
}
/// <summary>
/// Object mapping
/// </summary>
/// <returns></returns>
public static List<Employee> CreateObject()
{
var employeeList = new List<Employee>();
var employee = new Employee();
var employeeProjectList = new List<EmployeeProject>();
employee.Name = "John";
var employeeProject = new EmployeeProject();
employeeProject.ProjectName = "Chrome";
employeeProject.ClientName = "Google";
employeeProjectList.Add(employeeProject);
employeeProject = new EmployeeProject();
employeeProject.ProjectName = "WhatsApp";
employeeProject.ClientName = "Meta";
employeeProjectList.Add(employeeProject);
employee.EmployeeProject = employeeProjectList;
employeeList.Add(employee);
employee.Name = "Alex";
employeeProjectList = new List<EmployeeProject>();
employeeProject = new EmployeeProject();
employeeProject.ProjectName = "Chrome2";
employeeProject.ClientName = "Google2";
employeeProjectList.Add(employeeProject);
employeeProject = new EmployeeProject();
employeeProject.ProjectName = "WhatsApp2";
employeeProject.ClientName = "Meta2";
employeeProjectList.Add(employeeProject);
employee.EmployeeProject = employeeProjectList;
employeeList.Add(employee);
return employeeList;
}
/// <summary>
/// Linq function
/// </summary>
public static void LinqFunctionForNestedQuery()
{
var employeeObject = CreateObject();
var result1 = employeeObject.Select(x =>
{
x.EmployeeProject = x.EmployeeProject.Select(y =>
{
y.ProjectName.Contains("Chrome");
return y;
}).ToList();
return x;
});
}
uj5u.com熱心網友回復:
讓我們分部分進行。您的第一個代碼洗掉了串列中的功能,
for (var j = 0; j < features.Count(); j)
{
var feature = features[j];
if (feature.NodeFeatureTypeID
== FeatureTypeEnum.FEATURE_A
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_B
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_C
|| feature.FeatureTypeID == FeatureTypeEnum.FEATURE_D
)
{
features.RemoveAt(j);
}
}
我們需要將其轉換為“保持功能不在串列中”
var discard = new [] {FeatureTypeEnum.FEATURE_A, FeatureTypeEnum.FEATURE_B, FeatureTypeEnum.FEATURE_C, FeatureTypeEnum.FEATURE_D };
node.Features = node.Features.Where(f => !discard.Contains(f)).ToArray();
如果函式型別是某種型別,這部分代碼會跳過,如果函式型別不是某種型別,則將時間跨度歸零:
if (window.NodeFunctionTypeID == FeatureTypeEnum.MM_HOURS) continue;
window.StartHour = new TimeSpan(startTime, 0, 0);
window.EndHour = new TimeSpan(endTime, 0, 0);
作為僅對我們感興趣的事物進行操作的回圈,這可能會更好(我們只想修改那些 nodefuctionTypeId 不是“小時”的 Windows):
foreach(var window in node.Windows.Where(w => w.NodeFunctionTypeID != FeatureTypeEnum.MM_HOURS){
window.StartHour = new TimeSpan.FromHous(startTime);
window.EndHour = new TimeSpan.FromHours(endTime);
}
意思是整體是:
private void ApplyTransformation(InputPayload payload, int startTime = 8, int endTime = 15)
{
var discard = new [] {FeatureTypeEnum.FEATURE_A, FeatureTypeEnum.FEATURE_B, FeatureTypeEnum.FEATURE_C, FeatureTypeEnum.FEATURE_D };
foreach (var node in payload.Nodes)
{
node.Features = node.Features.Where(f => !discard.Contains(f)).ToArray();
foreach(var window in node.Windows.Where(w => w.NodeFunctionTypeID != FeatureTypeEnum.MM_HOURS){
window.StartHour = TimeSpan.FromHous(startTime);
window.EndHour = TimeSpan.FromHours(endTime);
}
}
}
我不認為我會將它全部轉換為 Linq 形式,因為它會弄得一團糟;linq 查詢不應該有副作用(修改查詢迭代的物件)所以特別是時間跨度被歸零的第二部分必須成為一個操作,如果你愿意,關于視窗的所有內容都被復制到一個新視窗來LINQ吧。
如果一個視窗實際上只是一個時間跨度對,那么它并沒有那么糟糕,或者如果您想提供一個接受現有視窗以及 startTime 和 endTime 的建構式:
public Window(Window copyFrom, int startTime, int endTime){
this.X = copyFrom.X;
this.Y = copyFrom.Y;
...
this.StartHour = TimeSpan.FromHours(strtTime);
this.EndHour = TimeSpan.FromHours(endTime);
}
那么也許你的方法可以變成一些 linq:
foreach (var node in payload.Nodes)
{
node.Features = node.Features.Where(f => !discard.Contains(f)).ToArray();
node.Windows = node.Windows.Select(w => w.NodeFunctionTypeID == FeatureTypeEnum.MM_HOURS ? w : new Window(w, startTime, endTime).ToArray();
}
..但我不知道我是否會嘗試批量替換整個節點串列,原因甚至基于方法的名稱:ApplyTransformations 聽起來像是“獲取此節點串列并更改它們的位”不是“獲取此節點串列并給我一個新串列,其中替換或修改了部分或全部節點”-如果呼叫代碼需要調整并且它發送的物件,代碼中的這種行為可能會破壞其他東西(或其中的物件)被換出新的
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/389757.html
下一篇:在條件運算式中重新拋出例外
