假设我有一个
数组{ "w", "w", "z", "a", "c", "r", "f", "d", "e", "c", "g", "f", "m", "z" }
我有一条规则,所有" c"应该在" f"之前移动。 遵循规则时尽可能保持与原始订单最接近的顺序的目标。 一个真实世界的例子是一个知道一些插件" A"应该高于某些插件" B"在加载列表中。
所以预期的结果是:
在第一个f:
之前移动了c{ "w", "w", "z", "a", "c", "r", "c"<<, "f", "d", "e", "g", "f", "m", "z" }
或
在最后一个c:
之后移动了f{ "w", "w", "z", "a", "c", "r", "d", "e", "c", >>"f", "g", "f", "m", "z" }
是否可以使用LINQ或任何可以用于此目的的东西?
我尝试了OrderBy(x => x == "c" ? 0 : x == "f" ? 1 : (int?)null)
,但它将元素移到了最后。我想只对彼此的特定元素进行排序,但在可能的情况下保持其相对于其他元素的位置。
更新
解决方案适用于任何输入:
public static char GetLetter(Random rand)
{
string chars = "abcdefghijklmnopqrstuvwxyz";
int num = rand.Next(0, chars.Length - 1);
return chars[num];
}
public static IEnumerable<string> Sort(IEnumerable<string> enumerable, string first, string second)
{
???
}
static void Main(string[] args)
{
Random rand = new Random();
string[] input = Enumerable.Range(1, 10).Select(x => GetLetter(rand) + "").ToArray();
var result = Sort(Sort(input, "c", "f"), "m", "e");
}
支持多个元素(&#34; m&#34;,&#34; c&#34;,&#34; f&#34;)和多个规则是理想的,如果它不会使事情复杂化太多
答案 0 :(得分:2)
此方法可以满足您的需求:
public static IEnumerable<string> Sort(this IEnumerable<string> enumerable, string first, string second)
{
return enumerable.TakeWhile(s => s != second)
.Concat(enumerable.SkipWhile(s => s != second).OrderBy(a => a != first));
}
这个想法是,首先列出部分直到第一个f
(在这种情况下)。然后将剩余部分附加到其上,首先按c
个字符排序。
缺点是列表被枚举两次(部分)。如果这是性能至关重要的,那么你应该选择一个只列举一次的替代方案。
答案 1 :(得分:1)
这是一个解决方案:
string[] ch = {"a", "c", "f", "d", "e", "c", "g", "f", "m"};
var res = ch.Select((item, index) => new { item, index })
.OrderBy(x => x.item == "c" ? 0 : Convert.ToInt32(x.index))
.Select(c => c.item).ToArray();
输出:
答案 2 :(得分:-1)
如果在正确理解你的问题,我认为你需要有一个数组规则,你将在其中定义规则,比如哪个字符应该首先出现。考虑到你的老年人,我在这里添加一个测试。您可以修改规则并使用它。
[Test]
public void CustomOrderByTests()
{
char[] ch = { 'a', 'c', 'f', 'd', 'e', 'c', 'g', 'f', 'm' };
char[] rules = { 'a', 'f', 'c' };
var result = rules.Intersect(ch).Union(ch);
char[] expected = { 'a', 'f', 'c', 'd', 'e', 'g', 'm' };
CollectionAssert.AreEqual(result, expected);
}
如果您希望在使用Array.Sort()
重载之前在同一位置重复元素,则会在不删除重复项的情况下缩短结果
Array.Sort(rules, ch);
现在你的ch
数组将有排序数组。