LINQ 是什么?一句话理解
LINQ(Language Integrated Query,语言集成查询)就是一股流:从原数据出发,经过一串操作节点(筛选→转换→排序→聚合),最终得到想要的结果。每个操作节点用 .方法() 连接。
LabVIEW 方式
数据在线中流动,沿线经过 For Loop → Case Structure → Sort VI → Mean VI,每个节点对数组做一件事
LINQ 方式
数据在链式调用中流动,经过 .Where() → .OrderBy() → .Average()
两种方式表达的是完全相同的逻辑——它们只是呈现形式不同。
过滤:Where() vs Case Structure
过滤
double[] readings = { 23.5, 18.2, 26.1, 15.8, 30.0, 22.3 };
// LINQ:一行过滤
var high = readings.Where(r => r > 20).ToArray();
// ↑ ↑ ↑
// 数据源 对每个元素 判定条件(Lambda)而在LabVIEW中的过滤,通常使用的是Case结构
转换:Select() vs For Loop 中的公式
如果你想对数组中每个元素做一个变换(乘 2、取平方、转字符串等),LabVIEW 里是在 For Loop 内部放一个运算节点。LINQ 中用 .Select():
转换
// LINQ:每个元素 × 2,然后转成 string
double[] readings = { 23.5, 18.2, 26.1, 15.8, 30.0, 22.3 };
var labels = readings
.Select(r => r * 2) // [47, 36.4, 52.2, 31.6, 60, 44.6]
.Select(r => $"{r:F1} °C") // ["47.0 °C", "36.4 °C", ...]
.ToArray();“LabVIEW 对照:For Loop 里放一个 Multiply 函数(× 2),输出线再连到 Format Into String VI(加 °C)。.Select() 本质上就是在虚拟的 For Loop 里放了一个 Lambda 表达式。”
排序:OrderBy() vs Sort 1D Array
排序
// 升序
var ascending = readings.OrderBy(r => r).ToArray();
// 降序
var descending = readings.OrderByDescending(r => r).ToArray();
// 按自定义规则排序(如按离 22 的距离)
var byDistance = readings.OrderBy(r => Math.Abs(r - 22.0)).ToArray();聚合:Average / Sum / Max / Min vs 统计 VI
全部一行搞定,每个都有 LabVIEW 等价节点:
| LINQ 方法 | LabVIEW VI | 示例 |
|---|---|---|
| .Average() | Mean.vi | readings.Average() → 22.65 |
| .Sum() | Add Array Elements.vi | readings.Sum() → 135.9 |
| .Max() | Array Max & Min.vi(上半) | readings.Max() → 30.0 |
| .Min() | Array Max & Min.vi(下半) | readings.Min() → 15.8 |
| .Count() | Array Size.vi | readings.Count() → 6 |
| .First() | Index Array(端子设 0) | readings.First() → 23.5 |
| .Last() | Index Array(端子设 N-1) | readings.Last() → 22.3 |
通常,可以把聚合串联在管线的末尾:
链式
// 链式:先过滤,再求平均(只计算 >20 的读数的平均值)
double avgHigh = readings.Where(r => r > 20).Average(); // 25.33在 LabVIEW 中这是两个节点——先 For Loop + Case Structure 过滤,再连到 Mean.vi。LINQ 用了 .Where().Average() 一行表达。
分组:GroupBy() vs LabVIEW 的实现方式
按某个标准把数据分成若干组——这在 LabVIEW 中通常需要手动写索引和循环。LINQ 一次调用完成:
分组
// 按"是否高温"分组
var groups = readings.GroupBy(r => r > 25 ? "高温" : "常温");
// 高温组: { 26.1, 30.0 }
// 常温组: { 23.5, 18.2, 15.8, 22.3 }
// 按个位数分组
var byDigit = readings.GroupBy(r => (int)r % 10);
// 个位=5: { 23.5, 15.8, 30.0 } 个位=8: { 18.2 } ...完整示例:一条 LINQ 管线 = 多个 LabVIEW 节点
业务需求:有一组电压读数,输出 "大于 5V 的读数,从高到低排列,只取前 3 个"。
LabVIEW
需要的节点(空间布局):
For Loop + Case Structure(过滤 >5V)
Sort 1D Array + Reverse(降序)
Array Subset(取前 3)
For Loop + Case Structure(过滤 >5V)
Sort 1D Array + Reverse(降序)
Array Subset(取前 3)
LINQ
var top3 = voltages
.Where(v => v > 5.0)
.OrderByDescending(v => v)
.Take(3)
.ToArray();总结与速查
| 操作 | LabVIEW | LINQ |
|---|---|---|
| 遍历数组 | Auto-Indexing For Loop | LINQ 方法链隐式遍历 |
| 过滤 | For Loop + Case Structure | .Where(x => condition) |
| 变换 | For Loop + 运算节点 | .Select(x => expression) |
| 排序(升) | Sort 1D Array.vi | .OrderBy(x => x) |
| 排序(降) | Sort + Reverse 1D Array | .OrderByDescending(x => x) |
| 取前 N 个 | Array Subset.vi | .Take(N) |
| 跳过前 N 个 | Array Subset(设 start) | .Skip(N) |
| 去重 | 较复杂 | .Distinct() |
| 求平均 | Mean.vi | .Average() |
| 求和 | Add Array Elements.vi | .Sum() |
| 分组 | 手动 While Loop + 条件 | .GroupBy(x => key) |
“记忆公式:
LINQ = source.Filter().Transform().Sort().Aggregate()
每个 .Method() 就是一个虚拟的 LabVIEW 节点
每个 Lambda x => ... 就是那个节点内部的运算逻辑
数据和 LabVIEW 的线一样,从左往右流过每一个操作”