I'm to create a helper method that returns a new array whose elements are the square of an original array. But when I run the code, the console returns "System.Double[]". How can I fix this?
Here's the method code:
static double[] powerOfTwo(int[] arr)
{
double[] elevatedPower = new double[10];
elevatedPower[0] = Math.Pow(arr[0], 2);
elevatedPower[1] = Math.Pow(arr[1], 2);
elevatedPower[2] = Math.Pow(arr[2], 2);
elevatedPower[3] = Math.Pow(arr[3], 2);
elevatedPower[4] = Math.Pow(arr[4], 2);
elevatedPower[5] = Math.Pow(arr[5], 2);
elevatedPower[6] = Math.Pow(arr[6], 2);
elevatedPower[7] = Math.Pow(arr[7], 2);
elevatedPower[8] = Math.Pow(arr[8], 2);
elevatedPower[9] = Math.Pow(arr[9], 2);
return elevatedPower;
}
And the code to print it in the console:
static void Main(string[] args)
{
double[] powerValues = powerOfTwo(new int[] {1,2,3,4,5,6,7,8,9,10});
Console.Write(powerValues);
Console.ReadLine();
}
Your method works fine. But when you do Console.WriteLine(powerValues), the compiler calls ToString() method of the datatype which is System.double[].
foreach(var value in powerValues)
Console.WriteLine(value);
With Linq, using System.Linq;
var powerValues = (new int[] {1,2,3,4,5,6,7,8,9,10}).Select(x => x*x);
Actually, you are not printing your values. You try to print your array which returns it's full type name as System.Double[] since ToString calls it which is called by Console.Write explicitly.
You don't even need such a method. Just use Enumerable.Select to generate IEnumerable<int> which contains squared values like;
var values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (var value in values.Select(i => i * i))
{
Console.Write(value); // 149162536496481100
}
And I would use Console.WriteLine to writing those values in separate lines each or put at least a white space after them if you choose Write like Console.Write(value + " ")
When you calling Console.Write(powerValues); actually call Console.Write(powerValues.ToString());ToString returns a string that represents the current object. For double[] this is "System.Double[]".
Change your code like this :
static void Main(string[] args)
{
double[] powerValues = powerOfTwo(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
foreach (var value in powerValues)
{
Console.WriteLine(value);
}
Console.ReadLine();
}
Write Your code in just simple one line using below code.
new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }.ToList().ForEach(i => Console.WriteLine(i * i));
and each value are display in new line so result are also good compare to other.
Related
I have two C# Lists of different sizes e.g.
List<int> list1 = new List<int>{1,2,3,4,5,6,7};
List<int> list2 = new List<int>{4,5,6,7,8,9};
I want to use the linq Zip method to combine these two into a list of tuples that is of the size list1. Here is the resulting list I am looking for
{(1,4), (2,5), (3,6), (4,7), (5,8), (6,9), (7,0)} //this is of type List<(int,int)
Since the last item of list1 does not has a counterpart in list2, I fill up my last item of the resulting list with a default value (in this case 0 as in my case it will never appear in any of the original lists).
Is there a way I can use the linq Zip method alone to achieve this?
You can use Concat to make them both the same size, and then zip it:
var zipped = list1.Concat(Enumerable.Repeat(0,Math.Max(list2.Count-list1.Count,0)))
.Zip(list2.Concat(Enumerable.Repeat(0,Math.Max(list1.Count-list2.Count,0))),
(a,b)=>(a,b));
Or create an extension method:
public static class ZipExtension{
public static IEnumerable<TResult> Zip<TFirst,TSecond,TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst,TSecond,TResult> func,
TFirst padder1,
TSecond padder2)
{
var firstExp = first.Concat(
Enumerable.Repeat(
padder1,
Math.Max(second.Count()-first.Count(),0)
)
);
var secExp = second.Concat(
Enumerable.Repeat(
padder2,
Math.Max(first.Count()-second.Count(),0)
)
);
return firstExp.Zip(secExp, (a,b) => func(a,b));
}
}
So you can use like this:
//last 2 arguments are the padder values for list1 and list2
var zipped = list1.Zip(list2, (a,b) => (a,b), 0, 0);
There is a useful and popular MoreLinq library. Install it and use.
using MoreLinq;
var result = list1.ZipLongest(list2, (x, y) => (x, y));
Try this using Zip function-
static void Main(string[] args)
{
List<int> firstList = new List<int>() { 1, 2, 3, 4, 5, 6, 0, 34, 56, 23 };
List<int> secondList = new List<int>() { 4, 5, 6, 7, 8, 9, 1 };
int a = firstList.Count;
int b = secondList.Count;
for (int k = 0; k < (a - b); k++)
{
if(a>b)
secondList.Add(0);
else
firstList.Add(0);
}
var zipArray = firstList.Zip(secondList, (c, d) => c + " " + d);
foreach(var item in zipArray)
{
Console.WriteLine(item);
}
Console.Read();
}
Or you can try this using ZipLongest Function by installing MoreLinq nuget package-
static void Main(string[] args)
{
List<int> firstList = new List<int>() { 1, 2, 3, 4, 5, 6, 0, 34, 56, 23 };
List<int> secondList = new List<int>() { 4, 5, 6, 7, 8, 9, 1 };
var zipArray = firstList.ZipLongest(secondList, (c, d) => (c,d));
foreach (var item in zipArray)
{
Console.WriteLine(item);
}
Console.Read();
}
Try this code-
static void Main(string[] args)
{
List<int> firstList=new List<int>() { 1, 2, 3, 4, 5, 6,0,34,56,23};
List<int> secondList=new List<int>() { 4, 5, 6, 7, 8, 9,1};
int a = firstList.Count;
int b = secondList.Count;
if (a > b)
{
for(int k=0;k<(a-b);k++)
secondList.Add(0);
}
else
{
for (int k = 0; k < (b-a); k++)
firstList.Add(0);
}
for(int i=0;i<firstList.Count;i++)
{
for(int j=0;j<=secondList.Count;j++)
{
if(i==j)
Console.Write($"({Convert.ToInt32(firstList[i])},{ Convert.ToInt32(secondList[j])})" + "");
}
}
Console.Read();
}
I wrote a method, that takes a multidimensional array as a parameter and returns the largest numbers of each:
static double[] FindLargest( double[][] NumsInNums ) {
double[] Larges = new double[] {};
int i = 0;
foreach( double[] Nums in NumsInNums ) {
Larges[i] = Nums.Max();
i++;
}
return Larges;
}
But when i call it:
static void Main(string[] args)
{
double[] nums = FindLargest( {{4, 2, 7, 1}, {20, 70, 40, 90}, {1, 2, 0}} );
foreach(double num in nums) {
Console.WriteLine(num);
}
}
But this error appers:
What is wrong here?
You have two problems. Firstly your array declaration has an invalid syntax. It should be like this:
var nums = FindLargest(
new []
{
new double[] { 4, 2, 7, 1},
new double[] { 20, 70, 40, 90},
new double[] { 1, 2, 0}
});
(I think that was probably OK in your actual code, because you seem to be asking about a different problem; see below!)
Secondly, in your FindLargest() method you are creating your result array, Larges with a size of zero. You need to create it with the correct size to accommodate all the results - in this case, it must be the same size as the NumsInNums array, which you can find via NumInNums.Length:
static double[] FindLargest(double[][] NumsInNums)
{
double[] Larges = new double[NumsInNums.Length];
int i = 0;
foreach (double[] Nums in NumsInNums)
{
Larges[i] = Nums.Max();
i++;
}
return Larges;
}
Just for completeness, I should point out that you can use the Linq Enumerable.Select() to simplify the code like so:
static double[] FindLargest(double[][] NumsInNums)
{
return NumsInNums.Select(array => array.Max()).ToArray();
}
The .Select() takes each element of NumInNums (each element is an array) and then calls Enumerable.Max() for it, then takes all the results and puts them in an array (via the ToArray()).
How can I check if all the elements from one array are in another array? I have a 2d array with 3 arrays in it,and I want to check all of those 3 arrays if they have all the elements from allnumbers. array1=allnumbers ? array2=allnumbers ? array1=allnumber2 ? I need to return true if at least one contains all the elements from allnumbers. I have the code bellow,but I need it not to contain more than 3 control flow statements.
// int[,][] array = {array1, array2, array3}
static bool CheckLine(int[,][] array)
{
const int maxL = 9;
bool result = false;
int[] allnumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var singlearray in array)
{
int[] arr = singlearray;
int p = 0;
foreach (var num in allnumbers)
{
foreach (var arraynumber in singlearray)
{
if (arraynumber == num)
{
p++;
}
}
if (p == maxL)
{
result = true;
break;
}
}
}
return result;
}
If the values in your array are unique, and you don't care about the order they're in, this is a job for HashSet. (In other words, if your arrays contain sets of numbers you can treat them as sets.) Here's the basic outline of comparing sets.
var allnumbersSet = new HashSet<int>(allnumbers);
var allnumbers2Set= new HashSet<int>(allnumbers2);
if (allnumbersSet.IsSupersetOf(allnumbers2Set)) {
/* everything in allnumbers2 is also in allnumbers1 */
}
The people who put together DotNet did a really good job creating and optimizing those collection classes; you can use them with confidence to get good performance.
It seems, that you have two-dimensional jagged array. You can simplify your code by using Except and check the difference between allnumbers array and single row at every loop iteration.
static bool CheckLine(int[,][] array)
{
int[] allnumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var singlearray in array)
{
var diff = allnumbers.Except(singlearray);
if (!diff.Any())
{
return true;
}
}
return false;
}
If there is no elements in a difference, it'll mean that single item from source 2D array has all elements from allnumbers array.
Example of the usage
var array = new int[2, 2][];
array[0, 0] = new[] { 1, 2, 8 };
array[0, 1] = new[] { 3, 4, 5, 6 };
array[1, 1] = new[] { 3, 2, 1, 4, 5, 7, 6, 10, 9, 8 };
array[1, 0] = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
CheckLine(array);
The last two items satisfy the condition, execution will break and return true for { 3, 2, 1, 4, 5, 7, 6, 10, 9, 8 } array. Also don't forget to add using System.Linq directive at the top of file
Thank you for your help. I forgot to mention that I can use only "using System;"
This question already has answers here:
printing all contents of array in C#
(13 answers)
Console.WriteLine(ArrayList) wrong output
(6 answers)
Closed 5 years ago.
In my program I'm trying to find the Mode from a list of integers. Logically wise my program is correct. However when I try to print out the Mode I get the following message "Mode: System.Collections.Generic.List'1[System.Int32]. The outcome I was expecting to print is "Mode: 2, 7" since these 2 numbers occur 3 times in the list of integers. What am I doing wrong here? Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mode
{
class Program
{
static void Main(string[] args)
{
Test();
}
static void Test()
{
int[] values = { 1, 6, 4, 7, 9, 2, 5, 7, 2, 6, 5, 7, 8, 1, 3, 8, 2 };
List<int> mode = new List<int>();
mode = Mode(values);
Console.WriteLine("Mode: {0}", mode);
Console.ReadLine();
}
static List<int> Mode(int[] values)
{
int[] sorted = new int[values.Length];
values.CopyTo(sorted, 0);
Array.Sort(sorted);
List<int> result = new List<int>();
var counts = new Dictionary<int, int>();
int max = 0;
foreach (int num in sorted)
{
if (counts.ContainsKey(num))
counts[num] = counts[num] + 1;
else
counts[num] = 1;
}
foreach (var key in counts.Keys)
{
if (counts[key] > max)
{
max = counts[key];
result.Add(max);
}
}
return result;
}
}
}
You are trying to string.Format and object from a reference type class that doesn't have a custom .ToString() implementation. I recommend the use of String.Join (reference here)
C#
Console.WriteLine("Mode: {0}", String.Join(", ", mode));
user DesertFox mentioned properly.
You are trying to print a list. Intead of that, as per your requirement, make it as a single string using String.Join.
Modify your test method like below
static void Test()
{
try
{
int[] values = { 1, 6, 4, 7, 9, 2, 5, 7, 2, 6, 5, 7, 8, 1, 3, 8, 2 };
List<int> mode = new List<int>();
mode = Mode(values);
Console.WriteLine("Mode: {0}", String.Join(", ", mode));
Console.ReadLine();
}
catch(Exception ex)
{
}
}
Output
Print the items in the list rather than the list itself.
If I have a string array, for example: var array = new[] { "the", "cat", "in", "the", "hat" }, and I want to join them with a space between each word I can simply call String.Join(" ", array).
But, say I had an array of integer arrays (just like I can have an array of character arrays). I want to combine them into one large array (flatten them), but at the same time insert a value between each array.
var arrays = new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, new { 7, 8, 9 }};
var result = SomeJoin(0, arrays); // result = { 1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9 }
I wrote something up, but it is very ugly, and I'm sure that there is a better, cleaner way. Maybe more efficient?
var result = new int[arrays.Sum(a => a.Length) + arrays.Length - 1];
int offset = 0;
foreach (var array in arrays)
{
Buffer.BlockCopy(array, 0, result, offset, b.Length);
offset += array.Length;
if (offset < result.Length)
{
result[offset++] = 0;
}
}
Perhaps this is the most efficient? I don't know... just seeing if there is a better way. I thought maybe LINQ would solve this, but sadly I don't see anything that is what I need.
You can generically "join" sequences via:
public static IEnumerable<T> Join<T>(T separator, IEnumerable<IEnumerable<T>> items)
{
var sep = new[] {item};
var first = items.FirstOrDefault();
if (first == null)
return Enumerable.Empty<T>();
else
return first.Concat(items.Skip(1).SelectMany(i => sep.Concat(i)));
}
This works with your code:
var arrays = new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, new { 7, 8, 9 }};
var result = Join(0, arrays); // result = { 1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9 }
The advantage here is that this will work with any IEnumerable<IEnumerable<T>>, and isn't restricted to lists or arrays. Note that this will insert a separate in between two empty sequences, but that behavior could be modified if desired.
public T[] SomeJoin<T>(T a, T[][] arrays){
return arrays.SelectMany((x,i)=> i == arrays.Length-1 ? x : x.Concat(new[]{a}))
.ToArray();
}
NOTE: The code works seamlessly because of using Array, otherwise we may lose some performance cost to get the Count of the input collection.
This may not be the most efficient, but it is quite extensible:
public static IEnumerable<T> Join<T>(this IEnumerable<IEnumerable<T>> source, T separator)
{
bool firstTime = true;
foreach (var collection in source)
{
if (!firstTime)
yield return separator;
foreach (var value in collection)
yield return value;
firstTime = false;
}
}
...
var arrays = new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, new[] { 7, 8, 9 }};
var result = arrays.Join(0).ToArray();
// result = { 1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9 }