0

I need to compare an array with a array model and complete the structure, like this example:

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

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

The model can't be changed, it's a reference array.

Any ideas about the best way to achieve this?

user3571412
  • 105
  • 1
  • 9

4 Answers4

4

You can do that like that:

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();

This will concat the missing elements from model at the end of array.


Concat, Skip and ToArray are LINQ extension methods declared in the Enumerable class in namespace System.Linq. So you need to add using System.Linq; to your code.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • I get the message "System.Array don't have a definition for 'Concat'", i forget any reference? – user3571412 Feb 14 '17 at 17:58
  • @user3571412 yes, they are LINQ extensions. Add `using System.Linq;`. Updated my answer. – René Vogt Feb 14 '17 at 18:00
  • This won't be the fastest. – Matthew Whited Feb 14 '17 at 18:01
  • 1
    @MatthewWhited That is surely true, but I can't see that performance was an issue for OP. There even may be contradicting criterias like "with least memory usage" or "with the shortest code". I only start micro-optimization if it's necessary. – René Vogt Feb 14 '17 at 18:07
  • 1
    @user3571412 I just now read your comment below your question that it's actually the _fastest_ you are looking for. So there are definitly faster answers here. Please remember to add those requirements to your question next time :) – René Vogt Feb 14 '17 at 18:25
3

Copy the short one into the long one:

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));

If best means fastest as you wrote in your comment then here is a comparison:

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);
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
2

If you know the array lengths upfront you can do this...

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

Array.Copy(array, model, array.Length);

if not you can so something like this...

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);

... fastest without mutation of originals ...

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);
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
-1

Here's my version... Might be a bit faster than LINQ. My assumption is you're replacing based on array with larger number but I may be wrong.

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];
    }
}

If not you can simply do an Array.Copy

Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
  • If you want fastest you will need to move the `array.Length` check before the loop. – Matthew Whited Feb 14 '17 at 18:03
  • Uh, I'm actually assuming the user already knows their array structure. – Chibueze Opata Feb 14 '17 at 18:07
  • yes, but this will call `array.Length` on each pass. do `var len = array.Length; for(var i = 0; i – Matthew Whited Feb 14 '17 at 18:10
  • Wow! I doubt this will have any performance significance, I've come across this before... any benchmark links? – Chibueze Opata Feb 14 '17 at 18:11
  • for 7 elements in debug... maybe. – Matthew Whited Feb 14 '17 at 18:18
  • That answer is not correct. If will look correct in debug but if you change to release it will show fast improvement on my example (assuming a large dataset) At this small the improvement is so tiny it's not really worth considering. – Matthew Whited Feb 14 '17 at 18:29
  • I agree with his cache explanation, and in addition, Marc Gravell can't be wrong at the same time. "there is a scenario where the JIT does something clever here; with arrays it spots the common < arr.Length case and bypasses some length overrun tests". – Marc Gravell♦ Jul 30 '10 at 8:41 – Chibueze Opata Feb 15 '17 at 13:52
  • If you do any more than the extermely simple example (such as access a second array to get the value to store in the first array) the cache will be lost and the loop will be slower. – Matthew Whited Feb 15 '17 at 14:39