如何优雅地将含数组的Compact对象列表扁平化为Flattened对象列表
解决方案
1. LINQ 简洁实现(最优雅)
核心使用LINQ的SelectMany方法展开集合,配合Zip方法配对相同下标的Number和Value数组元素,一行代码即可完成转换:
List<Flattened> flattenedList = c .SelectMany(compact => compact.Number .Zip(compact.Value, (num, val) => new Flattened(compact.Id, num, val))) .ToList();
该实现和您的预期输出完全一致,可读性高,适合绝大多数业务场景。
2. 高性能优化版本(适配超大规模数据)
如果需要处理的Compact对象数量极多、单个对象的数组长度很长,想要尽可能压缩性能开销,可以手动预分配结果列表容量,避免List动态扩容带来的性能损耗:
// 提前计算总元素数,预分配列表容量,减少扩容开销 int totalCount = c.Sum(x => x.Number.Length); List<Flattened> flattenedList = new List<Flattened>(totalCount); foreach (var compact in c) { // 数组长度校验,业务上能保证两个数组等长的话可以删除 if (compact.Number.Length != compact.Value.Length) throw new InvalidOperationException($"Id为{compact.Id}的Compact对象Number和Value数组长度不匹配"); for (int i = 0; i < compact.Number.Length; i++) { flattenedList.Add(new Flattened(compact.Id, compact.Number[i], compact.Value[i])); } }
性能对比说明
普通业务场景下LINQ版本和手写循环的性能差异在5%以内,优先选择可读性更高的LINQ版本;千万级以上元素规模的场景下,预分配容量的手写循环版本性能比LINQ版本高10%~20%左右。
注意事项
需要保证每个Compact对象的Number和Value数组长度一致,否则Zip方法只会取两个数组中长度较短的那个的元素,导致数据丢失。如果无法保证长度一致,建议增加长度校验逻辑。
内容的提问来源于stack exchange,提问作者Mads
相关产品推荐
相关产品推荐

