How to get Max value same length array in c# - c#

My array is below
int[] T1 = new int[]{1,5,4};
int[] T2 = new int[]{2,4,3};
int[] T3 = new int[]{7,9,1};
A result of the sequence I want it is as follows .
int[] result = {7,9,4}
I want to look for a max value same index[(e.g) 1,2,7) in array.
and Merging array is int[] result = {7,9,4}
please let me know best way
thanks

Here is a simple method for performing your desired operation.
int[] result = new int[T1.Length];
for (int i = 0; i < T1.Length; i++)
{
result[i] = new[] {T1[i], T2[i], T3[i]}.Max();
}
You'll have to add using System.Linq in order to enable the Max() extension.
EDIT
Here is a method that allows you to use any number of arrays:
static T[] MaxElements<T>(params T[][] arrays) where T : IComparable<T>
{
return Enumerable.Range(0, arrays[0].Length)
.Select(i => Enumerable.Range(0, arrays.Length)
.Select(a => arrays[a][i]).Max()).ToArray();
}
You'll have to add the using System.Linq; for this one too. You'll have to make sure that all the elements passed in have the same lengths else you will run into an IndexOutOfRangeException.
It can be used as follows;
var result = MaxElements(T1, T2, T3);

Here is what you need:
static void Main(string[] args)
{
GetMaxArray(new[] { 1, 5, 4 }, new[] { 2, 4, 3 }, new[] { 7, 9, 1 });
}
private static void GetMaxArray(params int[][] m)
{
var length = m.First().Length;
var r = new int[length];
for (var i = 0; i < length; i++)
r[i] = m.Select(a => a[i]).Max();
}

public int[] GetMaxValueArray(List<int[]> arrayList)
{
int[] result = null;
int maxArraySize;
int maxCurrentArrayItemValue;
if (arrayList != null && arrayList.Count > 0)
{
maxArraySize = 0;
foreach (int[] array in arrayList)
if (array.Length > maxArraySize)
maxArraySize = array.Length;
result = new int[maxArraySize];
for (int i = 0; i < maxArraySize; i++)
{
maxCurrentArrayItemValue = 0;
foreach (int[] array in arrayList)
if (i < array.Length)
if (array[i] > maxCurrentArrayItemValue)
maxCurrentArrayItemValue = array[i];
result[i] = maxCurrentArrayItemValue;
}
}
return result;
}

Related

Row-wise concatenate a list of jagged arrays in c#

I'd like help* in creating a method or (linq) expression that can row-wise concatenate lists (of varying lengths) of jagged arrays as the one below:
List<double[][]> orgArrayList = new List<double[][]>();
double[][] one = {
new [] {5d, 6},
new [] {7d, 9}};
double [][] two = {
new [] {5d, 6},
new [] {7d, 9}};
double [][] three= {
new [] {5d, 6},
new [] {7d, 9}};
orgArrayList.AddRange(new[] {one, two, three});
So that the resulting array will be equal to this one:
double[][] expected = {
new [] {5d, 6, 5, 6, 5, 6},
new [] {7d, 9, 7, 9, 7, 9}};
The number of jagged arrays in my input list(s) will be >=1. All arrays within a single list will be jagged with 2 dimensions, but none of the 2 dimensions will have a fixed/known length (size).
*'help' being a euphemism for someone telling me how to do it
You could start with something like this, which appends the elements of each row of add[] to the rows of src[], producing a new 2-dimensional array:
public static double[][] AppendToRows(double[][] src, double[][] add)
{
// Allocate new array to hold elements from src[] and add[]
double[][] res = new double[src.Length][];
// Append elements to each row of res[]
for (int i = 0; i < src.Length; i++)
{
// Allocate row res[i] large enough to hold elements from src[i] and add[i]
res[i] = new double[src[i].Length + add[i].Length];
// Copy/append elements from src[i] to res[i]
int ri = 0;
for (int j = 0; j < src[i].Length; j++)
res[i][ri++] = src[i][j];
// Copy/append elements from add[i] to res[i]
if (i >= add.Length)
continue;
for (int j = 0; j < add[i].Length; j++)
res[i][ri++] = add[i][j];
}
return res;
}
To append multiple arrays together, just call this method multiple times, once for each additional array that needs to be concatenated onto the resulting array.
A more comprehensive solution would be to take a List<double[][]> of input arrays, and to loop through each array in the list as you build each row of the result. But I have left that as an exercise for the reader.
You can create an extension, that will concatenate arrays the way you need, so it will looks like Linq:
public static class Extension
{
public static T[][] ConcatArrays<T>(this T[][] array, T[][] concatWith)
{
var max = Math.Max(array.Length, concatWith.Length);
var result = new T[max][];
for (var index = 0; index < max; index++)
{
var list = new List<T>();
if (index < array.Length)
{
list.AddRange(array[index]);
}
if (index < concatWith.Length)
{
list.AddRange(concatWith[index]);
}
result[index] = list.ToArray();
}
return result;
}
}
So the usage of this is:
var expected = one.ConcatArrays(two).ConcatArrays(three);
Hope it makes sense
As a final solution for my use case I simply combined David's and Valdimir's answer into a single method that can handle lists of varying lengths (>=1).
// ========================================
// My interpretation of David's suggestion
// using Valdimir's solution as a basis
// ========================================
public static double[][] RowWiseConcatListedJaggedArrays(List<double[][]> listOfJaggedArray)
{
var resArray = listOfJaggedArray[0];
for (int rInd = 1; rInd < listOfJaggedArray.Count; rInd++)
{
resArray = resArray.ConcatArrays(listOfJaggedArray[rInd]);
}
return resArray;
}
And putting everything together...
using System;
using System.Collections.Generic;
namespace RowWiseConcat
{
public static class Extension
{
// ====================
// Vladimir's solution
// ====================
public static T[][] ConcatArrays<T>(this T[][] array, T[][] concatWith)
{
var max = Math.Max(array.Length, concatWith.Length);
var result = new T[max][];
for (var index = 0; index < max; index++)
{
var list = new List<T>();
if (index < array.Length)
{
list.AddRange(array[index]);
}
if (index < concatWith.Length)
{
list.AddRange(concatWith[index]);
}
result[index] = list.ToArray();
}
return result;
}
}
class Program
{
// ========================================
// My interpretation of David's suggestion
// using Valdimir's solution as a basis
// ========================================
public static double[][] RowWiseConcatListedJaggedArrays(List<double[][]> listOfJaggedArray)
{
var resArray = listOfJaggedArray[0];
for (int rInd = 1; rInd < listOfJaggedArray.Count; rInd++)
{
resArray = resArray.ConcatArrays(listOfJaggedArray[rInd]);
}
return resArray;
}
static void Main(string[] args)
{
// ... do something that results in orgArrayList, e.g.
double[][] one =
{
new[] {5d, 6},
new[] {7d, 9}
};
double[][] two =
{
new[] {5d, 6},
new[] {7d, 9}
};
double[][] three =
{
new[] {5d, 6},
new[] {7d, 9}
};
List<double[][]> orgArrayList = new List<double[][]>()
{ one, two, three};
// Concat list items
var resArray = RowWiseConcatListedJaggedArrays(orgArrayList);
// ... continue with resArray
}
}
}

ReIndex Number List but keep Duplicates in Order C#

I'm trying to reorder a list that essentially gets rid of duplicates. Which I have been able to do. The part that is tripping me up is, if there are duplicates I want to keep them, and maintain the order
Examples -
Input = 1,3,3,4
Output = 1,2,2,3
Input = 1,3,5,6,6
Output = 1,2,3,4,4
Any help would be appreciated.
EDIT -
Code I've attempted.
for (int i = 1; i <= numList.Count; i++)
{
if (numList[i - 1] == numList[i])
{
foreach (var item in numList.Where(x => x == numList[i - 1]))
{
testList.Add(item);
i++;
}
foreach (var item in testList)
{
numList.Add(item);
}
}
else
{
numList[i - 1] = i;
}
}
Your question has nothing to with sorting... but I think I understood what you are looking for, and the following code should provide it:
List<Int32> numbers = new List<Int32> { 1, 3, 3, 4 };
List<Int32> result = new List<Int32>(numbers.Count);
Int32 currentValue = 1;
Int32 lastNumber = numbers[0];
for (Int32 i = 0; i < numbers.Count; ++i)
{
Int32 number = numbers[i];
if (numbers[i] != lastNumber)
++currentValue;
result.Add(currentValue);
lastNumber = number;
}
foreach (Int32 number in result)
Console.WriteLine(number); // Output: 1, 2, 2, 3
Please, visit this link to try a working demo, which implements the following function:
private static List<Int32> IndexNumbers(List<Int32> input)
{
List<Int32> numbers = input.OrderBy(x => x).ToList();
List<Int32> result = new List<Int32>(input.Count);
Int32 currentValue = 1;
Int32 lastNumber = numbers[0];
for (Int32 i = 0; i < numbers.Count; ++i)
{
Int32 number = numbers[i];
if (numbers[i] != lastNumber)
++currentValue;
result.Add(currentValue);
lastNumber = number;
}
return result;
}
Something like this? Note that it is unclear whether we expect the input to be out of order or not. If we're allowed to change the input array, a simple Array.Sort(values) at the top of Rebase would ensure that aspect.
static void Main(string[] args)
{
Console.WriteLine(string.Join(", ", Rebase(1, 3, 3, 4))); // 1, 2, 2, 3
Console.WriteLine(string.Join(", ", Rebase(1, 3, 5, 6, 6))); // 1, 2, 3, 4, 4
}
static int[] Rebase(params int[] values)
{
// Array.Sort(values); // if not already sorted, and allowed to mutate
int prev = values[0];
var result = new int[values.Length];
int val = result[0] = 1;
for (int i = 1; i < values.Length; i++)
{
var current = values[i];
if (current != prev)
{
val++;
prev = current;
}
result[i] = val;
}
return result;
}
Note that you could also choose to overwrite the input array rather than create a new array to return.
Try this using LINQ:
var reindexed = numList
.OrderBy(n => n)
.GroupBy(n => n)
.SelectMany((g, i) => g
.Select(e => i + 1));
First off, figure out what the old number should match to. Distinct and OrderBy are probably you're friends here
List<int> input = new List<int> { 1, 3, 3, 4 };
var dictionary = new Dictionary<int, int>();
var index = 1;
foreach (var n in input.Distinct().OrderBy(n => n)) {
dictionary.Add(n, index++);
}
var output = input.Select(n => dictionary[n]);

return array with elements that can be repeated only N times

I am trying to practice some c# questions and I came across a question where given an integer of array, return the array with elements that can be repeated only N times. So, if I have {1,2,3,4,1,1,2,3} and my N=2, my result should be {1,2,3,4,1,2,3}. I tried something but I get the result as {2,3,4,1,1,2,3}.I don't want the first repeated element be removed.
This is what I have tried :
int[] intArray = {3,2,3,1,3};
int N = 2;
var list = new List<int>(intArray);
var newList = new List<int>();
for (int i = 0; i < list.Count; i++)
{
int occur = 1;
for (int j = i+1; j < list.Count; j++)
{
if (occur < N && list[i] == list[j])
{
occur++;
newList.Add(list[j]);
}
else
{
if (list[i] == list[j] )
list.Remove(list[j]);
}
}
}
foreach (var l in list)
{
Console.WriteLine(l);
}
}
}
I would really appreciate any help or guidance.
I suggest using Dictionary<T, int> to count appearances:
private static IEnumerable<T> RepeatOnly<T>(IEnumerable<T> source, int times) {
Dictionary<T, int> counts = new Dictionary<T, int>();
foreach (var item in source) {
int count;
if (counts.TryGetValue(item, out count))
counts[item] = ++count;
else
counts.Add(item, count = 1);
if (count <= times)
yield return item;
}
}
....
int[] source = new int[] { 1, 2, 3, 4, 1, 1, 2, 3 };
int[] result = RepeatOnly(source, 2).ToArray();
Console.Write(string.Join(Environment.NewLine, result));
I'd use a dictionary to keep track of how many times each integer has been encountered:
int[] intArray = { 1, 2, 3, 4, 1, 1, 2, 3 };
int N = 2;
var lookup = new Dictionary<int, int>();
LIst<int> list = new List<int>();
foreach (int num in intArray)
{
if (!lookup.ContainsKey(num))
{
lookup[num] = 1;
list.Add(num);
}
else if (lookup[num]++ < N)
{
list.Add(num);
}
}

Index of longest word in a sentence using C#

If there are multiple string with same length(max), how do I find out all the indices. I am getting the first index currently. Is there a better way to do this?
using System;
using System.Linq;
namespace Examples
{
class Program
{
static void Main(string[] args)
{
Longestword("Find the largest word with lower index abcdefg ");
Console.ReadKey();
}
private static void Longestword(String sen)
{
String[] sArray = sen.Split(null);
int[] cArr = new int[sArray.Length];
for (int i = 0; i < sArray.Length; i++)
{
int j = sArray[i].Length;
cArr[i] = j;
}
int max = cArr.Max();
int index = cArr.ToList().IndexOf(max);
Console.WriteLine(index);
}
}
}
Here's my stab at a solution:
public static class LinqExtensions
{
public static List<int> IndicesOf(this int[] array, int item)
{
var indices = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] == item)
indices.Add(i);
}
return indices;
}
}
You can then call it like this:
int[] someArrayFindMax = new[] { 1, 4, 45, 23, 4, 3342, 34, 3342, 4, 3342, 3342 };
int max = someArrayFindMax.Max();
List<int> indices = someArrayFindMax.IndicesOf(max);
Here's another possible extension method for finding the indices of the longest strings directly:
public static List<int> LongestStringIndices(this string[] strings)
{
int longestString = -1;
var indices = new List<int>();
for (int i = 0; i < strings.Length; i++)
{
if (strings[i].Length > longestString)
{
longestString = strings[i].Length;
// We're no longer interested in the indices of the
// strings we now know to be shorter
indices.Clear();
indices.Add(i);
}
else if (strings[i].Length == longestString)
{
indices.Add(i);
}
// If it's less than the max length so far we ignore it
}
return indices;
}
I'd play with LINQ, as it's the C#-ish way.
Here's a fiddle: https://dotnetfiddle.net/NEFkqb
List<string> words = new List<string>{"aaaa","bb","cccc"};
List<int> lengths = words.Select(word => word.Length).ToList();
int max = lengths.Max();
List<int> maxes = new List<int>();
for(int i = 0; i < lengths.Count; i++)
if(lengths[i] == max)
maxes.Add(i);

Convert a List containing List<double> to single flatten array

to convert a list to array[,] there is code:
double[,] arr = new double[list.Count, list[0].Length];
for (int i = 0; i < list.Count; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i, j] = list[i][j];
}
}
I want to convert it to flatten array so Using the fact
Flattened array index computation
array[(Y coordinate * width) + X coordinate]
2D array index computation
array[Y coordinate, X coordinate]
code changes to
double[] arr = new double[list.Count * list[0].Length];
for (int i = 0; i < list.Count ; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i] = list[i * list[0].Length + j];
}
}
But What would be the code to convert a List < List < double > > to flatten array?
Is it possible to do it in 2 loops as the above code?
the List<List<double>> represents a double[,] arr
Honestly I'm not 100% sure what you're asking, but to flatten a List<List<>> you can use SelectMany from Linq, here's a simple example:
static void Main(string[] args)
{
var first = new List<double> {1, 2, 3};
var second = new List<double> { 3, 4, 5 };
var lists = new List<List<double>> {first, second};
var flatten = lists.SelectMany(a => a).ToArray();
foreach (var i in flatten)
{
Console.WriteLine(i);
}
}
Given the fact that your list ist a nested enumerable you can simply use Linq.
double[] array = nestedList.SelectMany(a => a).ToArray();
In a loop (i.e. without LINQ) would be something like
public static void Main()
{
List<List<double>> listOfLists = new List<List<double>>();
listOfLists.Add(new List<double>() { 1, 2, 3 });
listOfLists.Add(new List<double>() { 4, 6 });
int flatLength = 0;
foreach (List<double> list in listOfLists)
flatLength += list.Count;
double[] flattened = new double[flatLength];
int iFlat = 0;
foreach (List<double> list in listOfLists)
foreach (double d in list)
flattened[iFlat++] = d;
foreach (double d in flattened)
Console.Write("{0} ", d);
Console.ReadLine();
}

Categories

Resources