简体   繁体   English

如何用数组_c#Linq的最后一个索引替换数组的第二个和第三个索引?

[英]How Can I replace my second and third index of array with last index of array _c# Linq?

Actually I have a list like 其实我有一个清单

oldList= ['First','Second','Third',.....'Seventh'];

newArray should be like that newArray应该像这样

newArray=['First',.........'Seventh','Second','Third']

so How can I provide ordering like that with linq c#? 那么如何使用linq c#提供类似的订购?

I mean my first element should be kept at old place. 我的意思是我的第一个要素应该放在旧地方。 but I have to skip second and third elements to end of the list 但是我必须跳过第二和第三个元素到列表的末尾

Weird requirement, but you can use OrderBy even in this case: 奇怪的要求,但是即使在这种情况下,您也可以使用OrderBy

var newArray = oldList.Select((t, index) => new { t, index })
                      .OrderBy(x => x.index == 1 || x.index == 2)
                      .ThenBy(x => x.index)
                      .Select(x => x.t)
                      .ToArray();

Here's a demo: http://ideone.com/qJOlv 这是一个演示: http : //ideone.com/qJOlv

Yes, you can do this in LINQ, though it might not be the most efficient: 是的,您可以在LINQ中执行此操作,尽管它可能不是最有效的:

var newArray = oldList.Take(1)
    .Concat(oldList.Skip(3).Take(4))
    .Concat(oldList.Skip(1).Take(2))
    .ToArray();

However, if your original container is a List<T> you can do things a little more efficiently: 但是,如果您的原始容器是List<T> ,则可以更有效地执行操作:

var newList = oldList.GetRange(0, 1)
    .Concat(oldList.GetRange(3, 4))
    .Concat(oldList.GetRange(1, 2))
    .ToList();

UPDATE : 更新

For kicks and grins I went ahead and timed several of the proposed methods, and it looks like @LB's Get/Add/RemoveRange() comes on top: 对于踢脚和笑容,我继续进行了一些建议的方法的计时,而Get/Add/RemoveRange()Get/Add/RemoveRange()在最前面:

Over 100,000 iterations: 超过100,000次迭代:

  • Skip() / Take() took 82 ms (0.00082 ms / call) Skip()/ Take()花费了82毫秒(每次调用0.00082毫秒)
  • GetRange() / Concat() took 69 ms (0.00069 ms / call) GetRange()/ Concat()花了69毫秒(每次调用0.00069毫秒)
  • OrderBy() / ThenBy() took 145 ms (0.00145 ms / call) OrderBy()/ ThenBy()花费了145毫秒(0.00145毫秒/调用)
  • Add/Get/RemoveRange() took 21 ms (0.00021 ms / call) Add / Get / RemoveRange()花费了21毫秒(每次调用0.00021毫秒)

Of course, we're getting into microoptimization here, so I'd say go with the one that makes the most sense to you and is the most maintainable. 当然,我们正在这里进行微优化,所以我想说的是对您最有意义且最可维护的方法。 But it looks like LB's solution is the most performant (and is easy to read as well). 但是,看起来LB的解决方案是性能最高的(并且也易于阅读)。

If your collection is already a list, you can skip the first line 如果您的收藏集已经是列表,则可以跳过第一行

List<string> oldList2 = new List<string>(oldList);
var tmp = oldList2.GetRange(1, 2);
oldList2.RemoveRange(1, 2);
oldList2.AddRange(tmp);

LINQ is designed for querying data sources to produce new results, not mutating existing data. LINQ设计用于查询数据源以产生新结果,而不会使现有数据发生变异。

The general approach I would use to solve this problem: 我用来解决此问题的一般方法:

var second = array[1];
var third = array[2];

for(int i = 3; i < array.Length; i++)
{
    array[i-2] = array[i];
}

array[array.Length-2] = second;
array[array.Length-1] = third;

If you really, really need to use LINQ, I'd do something like this: 如果您确实需要使用LINQ,则可以执行以下操作:

var newArray = array.Take(1)
          .Concat(array.Skip(3))
          .Concat(array.Skip(1).Take(2))
          .ToArray();

Note that this approach iterates the data source 3 times; 请注意,此方法将数据源重复3次。 that's just fine if it's actually an array or list, but if, in reality, it's just an IEnumerable<T> thats the result of some query or complex operation that would be bad. 如果它实际上是数组或列表,那很好,但是实际上,如果它只是IEnumerable<T> ,那是不好的查询或复杂操作的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM