【问题标题】:Compare and complete two arrays比较并完成两个数组
【发布时间】:2017-02-14 17:48:20
【问题描述】:

我需要将数组与数组模型进行比较并完成结构,例如这个例子:

array = [0,1,2,3,4]
model = [0,0,0,0,0,0,0]

result = [0,1,2,3,4,0,0]

模型不能改变,它是一个引用数组。

关于实现这一目标的最佳方法的任何想法?

【问题讨论】:

  • 比较的依据是什么?更大、更小、相等?
  • @MongZhu 因为我的理解不同于零
  • 定义最佳。最快的?可能的代码更少? ...
  • 不要忘记Enumerable.Zip 例如。 array.Zip(model, (f, s) => f-s);
  • @CallbackKid 这将迭代到两个序列中较短的一个,因此它不会包含示例的尾随零。

标签: c# arrays


【解决方案1】:

你可以这样做:

var array = new[]{0,1,2,3,4};
var model = new[]{0,0,0,0,0,0,0};

var result = array.Concat(model.Skip(array.Length)).ToArray();

这会将model 中缺少的元素连接到array 的末尾。


ConcatSkipToArray 是在命名空间 System.Linq 中的 Enumerable 类中声明的 LINQ 扩展方法。所以你需要在你的代码中添加using System.Linq;

【讨论】:

  • 我收到消息“System.Array 没有 'Concat' 的定义”,我忘记了任何参考?
  • @user3571412 是的,它们是 LINQ 扩展。添加using System.Linq;。更新了我的答案。
  • 这不会是最快的。
  • @MatthewWhited 确实如此,但我看不出性能对 OP 来说是个问题。甚至可能存在相互矛盾的标准,例如“内存使用最少”或“代码最短”。我只在必要时才开始微优化。
  • @user3571412 我刚刚在您的问题下方阅读了您的评论,它实际上是您正在寻找的最快。所以这里肯定有更快的答案。请记住下次将这些要求添加到您的问题中:)
【解决方案2】:

将短的复制到长的:

int[] array = { 0, 1, 2, 3, 4 };
int[] model = { 0, 0, 0, 0, 0, 0, 0, };


int[] result = model;

array.CopyTo(result, 0);

Console.WriteLine(String.Join(" ", result));

如果你在评论中写的最好意味着最快,那么这里是一个比较:

Stopwatch st = new Stopwatch();

int[] array = new int[10000];
int[] model = new int[10200];

st.Start();
var asdf = array.Concat(model.Skip(array.Length)).ToArray();
st.Stop();
Console.WriteLine("Concat: " + st.ElapsedMilliseconds);


int[] arraya = new int[10000];
int[]  modela = new int[10200];

st.Restart();
int[] result = modela;
arraya.CopyTo(result, 0);
st.Stop();
Console.WriteLine("Copy: " + st.ElapsedMilliseconds);

【讨论】:

    【解决方案3】:

    如果你事先知道数组长度,你可以这样做......

    int[] array = { 0, 1, 2, 3, 4 };
    int[] model = { 0, 0, 0, 0, 0, 0, 0, };
    
    Array.Copy(array, model, array.Length);
    

    如果没有,你可以这样......

    int[] model = { 0, 1, 2, 3, 4 };
    var array = new int[7];
    
    var shorter = array.Length < model.Length ? array : model;
    var longer = array.Length >= model.Length ? array : model;
    Array.Copy(shorter, longer, shorter.Length);
    

    ...在不改变原件的情况下最快...

    int[] array = { 0, 1, 2, 3, 4 };
    int[] model = { 4,5,6,7,8,9,1, };
    
    var x = array.Length < model.Length ?
        new { s = array, l = model, sl = array.Length, ll = model.Length } :
        new { s = model, l = array, sl = model.Length, ll = array.Length };
    
    var result = new int[x.ll];
    
    Array.Copy(x.s, result, x.sl);
    Array.Copy(x.l, x.sl, result, x.sl, x.ll - x.sl);
    

    【讨论】:

    • 我认为 OP 不希望他的model 在操作期间被更改。
    • 如果只是复制到更大的数组,我会这样做。
    • 然后声明一个新数组并将两者都复制进去。Array.Copy 几乎是除了展开循环之外最快的选项。
    【解决方案4】:

    这是我的版本...可能比 LINQ 快一点。我的假设是你正在替换基于更大数字的数组,但我可能错了。

    var array = new[]{0,1,2,3,4};
    var model = new[]{0,0,0,0,0,0,0};
    for(int i = 0; i < array.Length; i++)
    {    
        if(array[i] > model[i])
        {
            model[i] = array[i];
        }
    }
    

    如果没有,你可以简单地做一个 Array.Copy

    【讨论】:

    • 如果你想要最快,你需要在循环之前移动array.Length检查。
    • 呃,我实际上假设用户已经知道他们的数组结构。
    • 是的,但这将在每次传递时调用array.Length。做var len = array.Length; for(var i = 0; i&lt;len;i++)) 会更快。
    • 哇!我怀疑这会对性能产生任何影响,我之前遇到过这个......任何基准链接?
    • 调试中的 7 个元素......也许吧。
    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 2021-05-13
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    相关资源
    最近更新 更多