Related
I am trying to do my homework but what I am trying does not work.
the assignment is to basically multiply 2 arrays of different sizes together( and put all three into a message box so if you could help me with as well that would be great)
the problem is that I am getting "overflow" amounts of values, there should only be 10 but I am getting like 28
the code I currently have is
double[] array1 = new Double[10] { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
double[] array2 = new Double[5] { 0, 1, 2, 3, 4 };
double[] array3 = new double[10];
int hold = 1;
int counter = 0;
foreach (int c in array1)
{
foreach(int k in array2)
{
if (counter <= k)
{
array3[c] = (array1[c] * array2[c]);//edit3: array2 was wirtten with c when copied th outcome different but still not rigth with k
}
else
{
array3[c] = (array1[c] * hold);
}
}
foreach (int j in array3)
{
Console.WriteLine(array3[c]);
}
}
the out come looks like
0
0
0
0
0
0
0
0
0
0
6
6
6
6
6
6
6
6
6
6
12
12
12
12
12
12
12
12
12
12
20
20
20
20
20
20
20
20
20
20
it should look like
0
2
6
12
20
6
7
8
9
10
I have check stackoverflow all ready, so please just help not link me to another question, or if you do put a comment with it saying what I need to look at.
edit: the array3 have j just gives ten 0
edit2: the debugger is telling me what I already know I am making too many
values, the question is how to fix this, and only make 10 values
There are so many mistakes in your code. You need only one loop:
double[] array1 = new Double[10] { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
double[] array2 = new Double[5] { 0, 1, 2, 3, 4 };
double[] array3 = new double[10];
int hold = 1;
int counter = 0;
for (int i = 0; i < array1.Length; i++)
{
if (i < array2.Length)
{
array3[i] = array1[i] * array2[i];
}
else
{
array3[i] = (array1[i] * hold);
}
}
foreach (int j in array3)
{
Console.WriteLine(j);
}
Since you have to write something that can do a multiplication of two arrays with (possible) different lengths, you could start with determining the longest array from the shortest one, and then iterate the shortest and concatenate the leftover to the resulting array (since that stays 1 in your example), you could do this for example through:
static IEnumerable<double> Multiply( double[] left, double[] right ) {
if ( left == null ) {
throw new ArgumentNullException( nameof(left));
}
if ( right == null ){
throw new ArgumentNullException( nameof(right));
}
var largest = left.Length > right.Length ? left : right;
var smallest = left.Length > right.Length ? right : left;
return smallest.Select( ( value, idx ) => value * largest[idx] )
.Concat( largest.Skip( largest.Length - smallest.Length ) );
}
This would give you an IEnumerable<double> result back as part of the function, and you could then use it in this way:
public static void Main( string[] args ) {
var array1 = new double[10] { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var array2 = new double[5] { 0, 1, 2, 3, 4 };
var multiplication = Multiply( array1, array2 );
foreach ( var item in multiplication ) {
Console.WriteLine( item );
}
Console.ReadLine();
}
Now, when looking into your original code, lets check some parts that where problematic in your version
double[] array3 = new double[10];
Declaring the array3 to a fixed size makes your code quite vulnerable, namely if array2 or array1 changes in length, the result size would also change? In my example, in is more dynamic, as it depends on the largest array of the two.
int counter = 0;
// ...
if (counter <= k)
you define a counter to be null, but it is never incremented in the shared code, because of that your code should have crashed when hitting array2[c] where c has a value larger than the largest index in array2, which kinda explains why it only goes till 20
foreach (int c in array1)
{
foreach(int k in array2)
foreach will set the variable c and k respectively to the next value of array1 and array2 upon each iteration, but in your code you are using it more as an indexer, so you should have used the. Furthermore, you are iterating a double[] and define the variable as int, that could give very confusing results, so you would have been easier of using
for (var c = 0; c < array1.Length; c++)
{
for (var k = 0; k < array2.Length; k++)
{
And now you can use them as indexes.
And the last one is that you where looping array3 using foreach inside the first foreach loop (thus repeating your iteration), while using c as an index for your array while it should have been j variable.
Now if you fix all these points you get something like Melchia's answer, but that is also a fragile one, for example, if you would switch array1 and array2 your code won't give the expected output anymore
im trying to multiply each element in three different arrays by 2 with a loop but im having trouble. im really new at this so please excuse any obvious mistakes lol im not even sure ive im using the right kind of loop but heres what i have so far:
int[] firstArray = new int[] { 1, 2, 5, 6, 9 };
int[] secondArray = new int[] { 12, 3, 8, 20, 7 };
int[] thirdArray = new int[] { 2, 4, 6, 8, 10, 12 };
foreach(new int [5] in firstArray)
{
int newArray1= firstArray.Length * 2;
Console.WriteLine(newArray1);
}
i want it to print out the first new array as "2, 4, 10, 12, 18" in the console but when i run it, i get the error type and identifier are both required in a foreach statement.
any help would be greatly appreciated!
Do this with Linq
int[] resultFirstArray = firstArray.Select(r=> r * 2).ToArray();
int[] resultSecondArray = secondArray.Select(r=> r * 2).ToArray();
int[] resultThirdArray = thirdArray.Select(r=> r * 2).ToArray();
Or you can use Array.ConvertAll
Array.ConvertAll converts an entire array. It converts all elements in one array to another type.
var resultFirstArray = Array.ConvertAll(firstArray, x => 2 * x);
var resultSecondArray = Array.ConvertAll(secondArray, x => 2 * x);
var resultThirdArray = Array.ConvertAll(thirdArray, x => 2 * x);
If you just want to show the doubled values:
foreach(int value in firstArray)
{
Console.WriteLine(2 * value);
}
If you want to double the values in the array, then:
for(int i = 0 ; i < firstArray.Length ; i++)
{
firstArray[i] *= 2;
}
Then perhaps to show those values:
foreach(int value in firstArray)
{
Console.WriteLine(value);
}
If you want to create a new array with the values doubled:
var doubledArray = Array.ConvertAll(firstArray, x => 2 * x);
And to output those values:
foreach(int value in doubledArray)
{
Console.WriteLine(value);
}
Is there any way to do the following?
int[,] multiArray = new int[5,5];
multiArray[0] = {0, 1, 3, 4, 5};
No, with multidimensional arrays, this is not possible. The array has a fixed size, and the compiler does not now what size you are allowed to assign to the array.
Also, how would the compiler know if you meant to do this:
multiArray[0, 0..4] = { 1, 2, 3, 4, 5 };
or this:
multiArray[0..4, 0] = { 1, 2, 3, 4, 5 };
However, you can use jagged arrays:
int[][] multiArray = new int[5][];
multiArray[0] = new[] { 1, 2, 3, 4, 5 };
I think what you want to do is save each element of the array into the same row but DIFFERENT columns of the multiArray.
multiArray[0][0] = 0;
multiArray[0][1] = 1;
multiArray[0][2] = 2;
multiArray[0][3] = 3;
multiArray[0][4] = 4;
multiArray[0][5] = 5;
I believe that is what you're trying to do. You can simplify this with a for loop as well.
Since .NET multidimensional arrays are stored in row-major order, you can use Buffer.BlockCopy for this operation (filling a full row at a time). Note the use of sizeof(int) since this method operates on bytes, not elements (unlike methods such as Array.Copy).
int[,] multiArray = new int[5, 5];
int rowIndex = 0;
int[] rowData = { 0, 1, 3, 4, 5 };
int destOffset = rowIndex * sizeof(int) * multiArray.GetLength(0);
Buffer.BlockCopy(rowData, 0, multiArray, destOffset, rowData.Length * sizeof(int));
I have multiple input arrays of Float all of equal size and a single dimension. I want to create a single output Array that contains the average of all the input arrays.
e.g.
//input arrays
float[] array1 = new float[] { 1, 1, 1, 1 };
float[] array2 = new float[] { 2, 2, 2, 2 };
float[] array3 = new float[] { 3, 3, 3, 3 };
float[] array4 = new float[] { 4, 4, 4, 4 };
//the output should be
float[2.5, 2.5, 2.5, 2.5]
I would also like to calculate the standard deviation of the input arrays to.
What is the fastest approach to do this task?
Thanks in advance.
Pete
LINQ to the rescue
This anwer details how to use LINQ to achieve the goal, with maximum reusability and versatility as the major objective.
Take 1 (package LINQ into a method for convenience)
Take this method:
float[] ArrayAverage(params float[][] arrays)
{
// If you want to check that all arrays are the same size, something
// like this is convenient:
// var arrayLength = arrays.Select(a => a.Length).Distinct().Single();
return Enumerable.Range(0, arrays[0].Length)
.Select(i => arrays.Select(a => a.Skip(i).First()).Average())
.ToArray();
}
It works by taking the range [0..arrays.Length-1] and for each number i in the range it calculates the average of the ith element of each array. It can be used very conveniently:
float[] array1 = new float[] { 1, 1, 1, 1 };
float[] array2 = new float[] { 2, 2, 2, 2 };
float[] array3 = new float[] { 3, 3, 3, 3 };
float[] array4 = new float[] { 4, 4, 4, 4 };
var averages = ArrayAverage(array1, array2, array3, array4);
This can already be used on any number of arrays without modification. But you can go one more step and do something more general.
Take 2 (generalizing for any aggregate function)
float[] ArrayAggregate(Func<IEnumerable<float>, float> aggregate, params float[][] arrays)
{
return Enumerable.Range(0, arrays[0].Length)
.Select(i => aggregate(arrays.Select(a => a.Skip(i).First())))
.ToArray();
}
This can be used to calculate any aggregate function:
var output = ArrayAggregate(Enumerable.Average, array1, array2, array3, array4);
Instead of Enumerable.Average you can substitute any method, extension method, or anonymous function -- which is useful, as there's no built-in standard deviation aggregate function and also this way the ArrayAggregate function is very versatile. But we can still do better.
Take 3 (generalizing for any aggregate function and any type of array)
We can also make a generic version that works with any built-in type:
T[] ArrayAggregate<T>(Func<IEnumerable<T>, T> aggregate, params T[][] arrays)
{
return Enumerable.Range(0, arrays[0].Length)
.Select(i => aggregate(arrays.Select(a => a.Skip(i).First())))
.ToArray();
}
As you can probably tell, this is not the fastest code to do the job. If your program spends all day calculating averages, use something more close to the metal. However, if you want reusability and versatility I don't think you can do much better than the above.
The fastest way in terms of performance, unless you'd like to unroll the for loop is
float[] sums = new float[4];
for(int i = 0; i < 4; i++)
{
sums[i] = (array1[i]+ array2[i] + array3[i] + array4[i])/4;
}
static void Main()
{
float[] array1 = new float[] { 1, 1, 1, 1 };
float[] array2 = new float[] { 2, 2, 2, 2 };
float[] array3 = new float[] { 3, 3, 3, 3 };
float[] array4 = new float[] { 4, 4, 4, 4 };
float[] avg = CrossAverage (array1, array2, array3, array4);
Console.WriteLine (string.Join ("|", avg.Select(f => f.ToString ()).ToArray()));
}
private static float[] CrossAverage (params float [][] arrays)
{
int [] count = new int [arrays[0].Length];
float [] sum = new float [arrays[0].Length];
for (int j = 0; j < arrays.Length; j++)
{
for (int i = 0; i < count.Length; i++)
{
count[i] ++;
sum[i] += arrays[j][i];
}
}
float [] avg = new float [arrays[0].Length];
for (int i = 0; i < count.Length; i++)
{
avg[i] = sum[i] / count[i];
}
return avg;
}
Don't forget bounds checking and divide by 0 checking.
And for the standard deviation after calculating the averages (into the sums array):
// std dev
float[] stddevs = new float[4];
for (int i = 0; i < 4; i++)
{
stddevs[i] += (array1[i] - sums[i]) * (array1[i] - sums[i]);
stddevs[i] += (array2[i] - sums[i]) * (array2[i] - sums[i]);
stddevs[i] += (array3[i] - sums[i]) * (array3[i] - sums[i]);
stddevs[i] += (array4[i] - sums[i]) * (array4[i] - sums[i]);
}
for (int i = 0; i < 4; i++)
stddevs[i] = (float)Math.Sqrt(stddevs[i]/4);
In general, accessing the array directly rather than using LINQ will be a performance win due to allowing the compiler/JIT to optimize. At the very least, array bounds checks can be eliminated and the overhead of using an enumerator will be avoided.
Lets say I have this array,
int[] numbers = {1, 3, 4, 9, 2};
How can I delete an element by "name"? , lets say number 4?
Even ArrayList didn't help to delete?
string strNumbers = " 1, 3, 4, 9, 2";
ArrayList numbers = new ArrayList(strNumbers.Split(new char[] { ',' }));
numbers.RemoveAt(numbers.IndexOf(4));
foreach (var n in numbers)
{
Response.Write(n);
}
If you want to remove all instances of 4 without needing to know the index:
LINQ: (.NET Framework 3.5)
int[] numbers = { 1, 3, 4, 9, 2 };
int numToRemove = 4;
numbers = numbers.Where(val => val != numToRemove).ToArray();
Non-LINQ: (.NET Framework 2.0)
static bool isNotFour(int n)
{
return n != 4;
}
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = Array.FindAll(numbers, isNotFour).ToArray();
If you want to remove just the first instance:
LINQ: (.NET Framework 3.5)
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIndex = Array.IndexOf(numbers, numToRemove);
numbers = numbers.Where((val, idx) => idx != numIndex).ToArray();
Non-LINQ: (.NET Framework 2.0)
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIdx = Array.IndexOf(numbers, numToRemove);
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(numIdx);
numbers = tmp.ToArray();
Edit: Just in case you hadn't already figured it out, as Malfist pointed out, you need to be targetting the .NET Framework 3.5 in order for the LINQ code examples to work. If you're targetting 2.0 you need to reference the Non-LINQ examples.
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = numbers.Except(new int[]{4}).ToArray();
You can also convert your array to a list and call remove on the list. You can then convert back to your array.
int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);
The code that is written in the question has a bug in it
Your arraylist contains strings of " 1" " 3" " 4" " 9" and " 2" (note the spaces)
So IndexOf(4) will find nothing because 4 is an int, and even "tostring" would convert it to of "4" and not " 4", and nothing will get removed.
An arraylist is the correct way to go to do what you want.
I posted my solution here.
This is a way to delete an array element without copying to another array - just in frame of the same array instance:
public static void RemoveAt<T>(ref T[] arr, int index)
{
for (int a = index; a < arr.Length - 1; a++)
{
// moving elements downwards, to fill the gap at [index]
arr[a] = arr[a + 1];
}
// finally, let's decrement Array's size by one
Array.Resize(ref arr, arr.Length - 1);
}
Removing from an array itself is not simple, as you then have to deal with resizing. This is one of the great advantages of using something like a List<int> instead. It provides Remove/RemoveAt in 2.0, and lots of LINQ extensions for 3.0.
If you can, refactor to use a List<> or similar.
Balabaster's answer is correct if you want to remove all instances of the element. If you want to remove only the first one, you would do something like this:
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int firstFoundIndex = Array.IndexOf(numbers, numToRemove);
if (numbers >= 0)
{
numbers = numbers.Take(firstFoundIndex).Concat(numbers.Skip(firstFoundIndex + 1)).ToArray();
}
As a generic extension, 2.0-compatible:
using System.Collections.Generic;
public static class Extensions {
//=========================================================================
// Removes all instances of [itemToRemove] from array [original]
// Returns the new array, without modifying [original] directly
// .Net2.0-compatible
public static T[] RemoveFromArray<T> (this T[] original, T itemToRemove) {
int numIdx = System.Array.IndexOf(original, itemToRemove);
if (numIdx == -1) return original;
List<T> tmp = new List<T>(original);
tmp.RemoveAt(numIdx);
return tmp.ToArray();
}
}
Usage:
int[] numbers = {1, 3, 4, 9, 2};
numbers = numbers.RemoveFromArray(4);
You can do in this way:
int[] numbers= {1,3,4,9,2};
List<int> lst_numbers = new List<int>(numbers);
int required_number = 4;
int i = 0;
foreach (int number in lst_numbers)
{
if(number == required_number)
{
break;
}
i++;
}
lst_numbers.RemoveAt(i);
numbers = lst_numbers.ToArray();
' To remove items from string based on Dictionary key values.
' VB.net code
Dim stringArr As String() = "file1,file2,file3,file4,file5,file6".Split(","c)
Dim test As Dictionary(Of String, String) = New Dictionary(Of String, String)
test.Add("file3", "description")
test.Add("file5", "description")
stringArr = stringArr.Except(test.Keys).ToArray()
public int[] DeletePart(int position, params int[] numbers)
{
int[] result = new int[numbers.Length - 1];
int z=0;
for (int i = 0; i < numbers.Length; i++)
{
if (position - 1 != i)
{
result[z] = numbers[i];
z++;
}
}
return result;
}
We can delete array elements by using for loops and continue statements:
string[] cars = {"volvo", "benz", "ford", "bmw"};
for (int i = 0; i < cars.Length; i++)
{
if (cars[i] == "benz")
{
continue;
}
Console.WriteLine(cars[i]);
}