以自定义方式重新排序数组
本文关键字:排序 数组 自定义 方式重 新排序 | 更新日期: 2023-09-27 18:05:27
我有一个按以下顺序打印为pdf的项目数组。例如:
lines = {1, 2, 3,
4, 5, 6,
7, 8, 9,
10}
是数组的内容。
但是我想把数组中元素的顺序改为
{1, 4, 7,
2, 5, 8,
3, 6, 9,
10}
然后我将这个数组传递给打印引擎。基本上,如果数组中有超过3个项目,我的新代码应该重新排序。
谁能帮我弄清楚这个逻辑吗?
谢谢
按行索引与行数的模数排序
public static ICollection<T> Sort<T>(ICollection<T> lines, int columns)
{
var rows = lines.Count/columns;
if (rows == 0)
{
return lines;
}
return lines.Select((line, i) => new {line, i})
.OrderBy(item => item.i < columns*rows ? item.i%rows : rows)
.Select(item => item.line)
.ToList();
}
Edit:或者您可以使用迭代器方法和列表的索引器来代替LINQ:
public static IEnumerable<T> Sort<T>(IList<T> lines, int columns)
{
var rows = lines.Count/columns;
for (var i = 0; i < lines.Count; i++)
{
var index = rows > 0 && i < columns*rows
? (i%columns)*rows + i/columns
: i;
yield return lines[index];
}
}
假设"对于线性数组,假设每9个元素构成3x3矩阵,对每个子序列进行转置,余数保持不变":
// assuming T[] items;
var toTranspose = (items.Count() / 9) * 9;
var remap = new int[]{1, 4, 7, 2, 5, 8, 3, 6, 9 };
var result = Enumerable.Range(0, toTranspose)
.Select(pos => items[(pos / 9) * 9 + (remap[pos % 9] - 1)])
.Concat(items.Skip(toTranspose)
.ToArray();
代码摘要:
- 获取需要移动的物品数量(即9个物品的组数
int numberOfGroup = Count()/9;
,乘以组大小) - 在
remap
数组中有自定义转换(注意索引按原样从样本复制,实际上是off-by- 1,因此-1
在计算索引中) - 对
toTranspose
下各元素指标从对应的组中获取源元素,并与remap
进行变换。 - 最后
Concat
剩余的。
指出:
- 如果需要,
- 可以很容易地提供自定义转换或内联换位。
- 不能对最后的部分组应用转换,因为元素必须移动到不存在的位置。