I have following code.
class Solution
{
static void Main(String[] args)
{
var matrix = new List<List<int>>();
for (int i = 0; i < 6; ++i)
{
string[] elements = Console.ReadLine().Split(' ');
matrix.Add(new List<int>());
foreach (var item in elements)
{
matrix[i].Add(int.Parse(item));
}
}
}
}
I know to print out the array which we read from console, convert it to int from string, we will have to use foreach loop. But here to print out the list in the console how can we write the code?
Print the values line by line:
foreach (var line in matrix)
{
foreach (var item in line)
{
Console.Write(item+"\t");
}
Console.WriteLine();
}
Related
Please I need help to sort the following string in csv format alphabetically
Input
First, Second,Third,Fourth, Fifth
Beth,Charles,Danielle,Adam,Eric\n
17945,10091,10088,3907,10132\n
2,12,13,48,11
Output (After sorting)
First, Second,Third,Fourth, Fifth
Adam,Beth,Charles,Danielle,Eric\n
3907,17945,10091,10088,10132\n
48,2,12,13,11
This is what I have tried.
First I converted the csv into datatable
var rows = csv.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var dtCsv = new DataTable();
for (int i = 0; i < rows.Count(); i++)
{
string[] rowValues = rows[i].Split(','); //split each row with comma to get individual values
{
if (i == 0)
{
for (int j = 0; j < rowValues.Count(); j++)
{
dtCsv.Columns.Add(rowValues[j]); //add headers
}
}
else
{
//DataRow dr = dtCsv.NewRow();
for (int k = 0; k < rowValues.Count(); k++)
{
//dr[k] = rowValues[k].ToString();
dtCsv.Columns.Add(rowValues[k]);
}
// dtCsv.Rows.Add(dr); //add other rows
}
}
}
Then I tried to convert back to csv hoping i can be able to sort the datatable, but I am hooked.
I appreciate in advcance.
Please I would appreciate a diferent approach if possible.
Although the model of data that you presented is not normal and accurate as Row, Column model, you can do it as per the below snippet code:
static void Main(string[] args)
{
Dictionary<int, List<string>> myDummyDic = ReadDataFromCsv();
foreach (var item in myDummyDic[0])
{
Console.WriteLine(item);
}
}
private static Dictionary<int, List<string>> ReadDataFromCsv()
{
Dictionary<int, List<string>> myDummyDic = new();
var result = File.ReadLines("data.csv")
.Select(line => line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList());
int rowC = 0;
foreach (var item in result)
{
List<string> lst = new();
for (int i = 0; i < item.Count; i++)
{
lst.Add(item[i]);
}
lst.Sort();
myDummyDic.Add(rowC++, lst);
}
return myDummyDic;
}
The output result:
Note that if you want to Transpose your CSV file entirely then I suggest you use Cinchoo ETL for that purpose.
Consider the following Question and Answers :
How to transpose matrix?
An approach without external library
Another approach using Cinchoo ETL to Transpose
I have the following code below that reads in text file and searches it for integers. I am using 'int.TryParse' to do this but it is not storing the integer values in the lists after it has run, just wondering if you could tell me what is wrong with this code. Thanks.
namespace AccessErrorFile
{
class Program
{
static void Main(string[] args)
{
List<int> plans = new List<int>();
List<int> events = new List<int>();
using (var reader = new StreamReader(#"D:\Temp\AccessEmail.txt"))
try
{
string line;
while ((line = reader.ReadLine()) != null)
{
//split the line
string[] parts = line.Split(new[] { "Event" }, StringSplitOptions.None);
//get valid integers
plans.Add(GetInt(parts[0].Split(' ', '\'')));
events.Add(GetInt(parts[1].Split(' ', '\'')));
}
}
catch (System.Exception ex)
{
Console.WriteLine("Error" + ex.Message);
}
//print the elements in the lists
foreach (int x in plans)
{
Console.WriteLine(x);
}
foreach (int y in events)
{
Console.WriteLine(y);
}
//print the number of elements in the lists
Console.WriteLine(plans.Count);
Console.WriteLine(events.Count);
Console.ReadLine();
}
public static int GetInt(string[] a)
{
int i = 0;
foreach (string s in a)
int.TryParse(s, out i);
return i;
}
}
}
your problem is
public static int GetInt(string[] a)
{
int i = 0;
foreach (string s in a) //HERE
int.TryParse(s, out i); //AND HERE
return i;
}
you are parsing in the loop, so the return i statement returns basically the last s of iteration, which, most probably is not a number, so i=0.
If you want to add all numbers from the string to array of ints, you can do something like:
IEnumerable<int> GetNumbersFromList(string[] s) {
foreach(var str in s) {
int val;
if(int.TryParse(str, out val))
yield return val;
}
}
and after
plans.AddRange(GetNumbersFromList(parts));
Just a basic idea, naturally, you have to fit it to your needs.
I want to print all the data line by line where each line contains "n" number of digits, n being user defined.
Something like:
void Print(List<int> list, int charactersPerLine)
{
// TODO: magic here
}
Usage
List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 }
Print(list, 4);
Desired output:
1234
5678
So far I tried:
List.AddRange(array);
List.Add(array2);
List.Add(array3);
foreach (int i in List)
{
Console.Write("{0}", i);
}
and when the loop writes to the console everything in the List<int> is written in a line, and the output is like:
12345678
Is this possible?
Use:
foreach (int i in List)
{
Console.WriteLine("{0}", i);
}
If your input is in {1,2,3,4,5,6,7,8} format you have to use some condition when to use Console.WriteLine() or Console.Write()
const int LineCharacterLimit = 4;
int i = 0;
foreach (int i in List)
{
i++;
if (i == LineCharacterLimit)
{
Console.WriteLine("{0}", i);
i=0;
}
else
{
Console.Write("{0}", i);
}
}
You could use String Builder first. Then just put a \n after each line.
StringBuilder str = new StringBuilder();
int count = 1;
foreach (int i in List)
{
str.Append(i.ToString());
if(count%4 ==0)
str.Append("\n");
count++;
}
Console.Write(str.ToString());
More generic version:
static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
int currentBatchSize = 0;
List<T> batch = new List<T>();
foreach (var e in source)
{
batch.Add(e);
if (++currentBatchSize % batchSize == 0)
{
yield return batch;
batch.Clear();
}
}
yield return batch;
}
}
I'm sure you can find something like this in morelinq package.
Usage:
static void Print(List<int> list, int charactersPerLine)
{
foreach (var batch in list.Batch(charactersPerLine))
{
var strBatch = batch.Select(e => e.ToString()).ToArray();
Console.WriteLine(string.Join(",", strBatch));
}
}
I want to be able to write some values to a file whilst creating blank lines in between. Here is the code that I have so far:
TextWriter w_Test = new StreamWriter(file_test);
foreach (string results in searchResults)
{
w_Test.WriteLine(Path.GetFileNameWithoutExtension(results));
var list1 = File.ReadAllLines(results).Skip(10);
foreach (string listResult in list1)
{
w_Test.WriteLine(listResult);
}
}
w_Test.Close();
This creates 'Test' with the following output:
result1
listResult1
listResult2
result2
listResult3
result3
result4
I want to write the results so that each result block is 21 lines in size before writing the next, e.g.
result1
(20 lines even if no 'listResult' found)
result2
(20 lines even if no 'listResult' found)
etc.......
What would be the best way of doing this??
TextWriter w_Test = new StreamWriter(file_test);
foreach (string results in searchResults)
{
int noLinesOutput = 0;
w_Test.WriteLine(Path.GetFileNameWithoutExtension(results));
noLinesOutput++;
var list1 = File.ReadAllLines(results).Skip(10);
foreach (string listResult in list1)
{
w_Test.WriteLine(listResult);
noLinesOutput++;
}
for ( int i = 20; i > noLinesOutput; i-- )
w_Test.WriteLine();
}
w_Test.Close();
Here's a simple helper method I use in such cases:
// pad the sequence with 'elem' until it's 'count' elements long
static IEnumerable<T> PadRight<T>(IEnumerable<T> enm,
T elem,
int count)
{
int ii = 0;
foreach(var elem in enm)
{
yield return elem;
ii += 1;
}
for (; ii < count; ++ii)
{
yield return elem;
}
}
Then
foreach (string listResult in
PadRight(list1, "", 20))
{
w_Test.WriteLine(listResult);
}
should do the trick.
Perhaps with this loop:
var lines = 20;
foreach(string fullPath in searchResults)
{
List<string> allLines = new List<string>();
allLines.Add(Path.GetFileNameWithoutExtension(fullPath));
int currentLine = 0;
foreach(string line in File.ReadLines(fullPath).Skip(10))
{
if(++currentLine > lines) break;
allLines.Add(line);
}
while (currentLine++ < lines)
allLines.Add(String.Empty);
File.WriteAllLines(fullPath, allLines);
}
I am using a hashtable to read data from file and make clusters.
Say the data in file is:
umair,i,umair
sajid,mark,i , k , i
The output is like:
[{umair,umair},i]
[sajid,mark,i,i,k]
But my code does not work. Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
namespace readstringfromfile
{
class Program
{
static void Main()
{
/* int i = 0;
foreach (string line in File.ReadAllLines("newfile.txt"))
{
string[] parts = line.Split(',');
foreach (string part in parts)
{
Console.WriteLine("{0}:{1}", i,part);
}
i++; // For demo only
}*/
Hashtable hashtable = new Hashtable();
using (StreamReader r = new StreamReader("newfile.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
string[] records = line.Split(',');
foreach (string record in records)
{
if (hashtable[records] == null)
hashtable[records] = (int)0;
hashtable[records] = (int)hashtable[records] + 1;
Console.WriteLine(hashtable.Keys);
}
/////this portion is not working/////////////////////////////////////
foreach (DictionaryEntry entry in hashtable)
{
for (int i = 0; i < (int)hashtable[records]; i++)
{
Console.WriteLine(entry);
}
}
}
}
}
}
}
You're working with the records array when inserting into the hashtable (and when reading from it) instead of using the foreach-variable record. Also, in the final look, you iterate based on records instead of the current entry.Key. You're also declaring the hashtable in a too wide scope, causing all rows to be inserted into the same hashtable, instead of one per row.
public static void Main() {
var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" };
foreach (var line in lines) {
var hashtable = new Hashtable();
var records = line.Split(',');
foreach (var record in records) {
if (hashtable[record] == null)
hashtable[record] = 0;
hashtable[record] = (Int32)hashtable[record] + 1;
}
var str = "";
foreach (DictionaryEntry entry in hashtable) {
var count = (Int32)hashtable[entry.Key];
for (var i = 0; i < count; i++) {
str += entry.Key;
if (i < count - 1)
str += ",";
}
str += ",";
}
// Remove last comma.
str = str.TrimEnd(',');
Console.WriteLine(str);
}
Console.ReadLine();
}
However, you should consider using the generic Dictionary<TKey,TValue> class, and use a StringBuilder if you're building alot of strings.
public static void Main() {
var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" };
foreach (var line in lines) {
var dictionary = new Dictionary<String, Int32>();
var records = line.Split(',');
foreach (var record in records) {
if (!dictionary.ContainsKey(record))
dictionary.Add(record, 1);
else
dictionary[record]++;
}
var str = "";
foreach (var entry in dictionary) {
for (var i = 0; i < entry.Value; i++) {
str += entry.Key;
if (i < entry.Value - 1)
str += ",";
}
str += ",";
}
// Remove last comma.
str = str.TrimEnd(',');
Console.WriteLine(str);
}
Console.ReadLine();
}
You're attempting to group elements of a sequence. LINQ has a built-in operator for that; it's used as group ... by ... into ... or the equivalent method .GroupBy(...)
That means you can write your code (excluding File I/O etc.) as:
var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" };
foreach (var line in lines) {
var groupedRecords =
from record in line.Split(',')
group record by record into recordgroup
from record in recordgroup
select record;
Console.WriteLine(
string.Join(
",", groupedRecords
)
);
}
If you prefer shorter code, the loop be equivalently written as:
foreach (var line in lines)
Console.WriteLine(string.Join(",",
line.Split(',').GroupBy(rec=>rec).SelectMany(grp=>grp)));
both versions will output...
umair,umair,i
sajid,mark,i,i,k
Note that you really shouldn't be using a Hashtable - that's just a type-unsafe slow version of Dictionary for almost all purposes. Also, the output example you mention includes [] and {} characters - but you didn't specify how or whether they're supposed to be included, so I left those out.
A LINQ group is nothing more than a sequence of elements (here, identical strings) with a Key (here a string). Calling GroupBy thus transforms the sequence of records into a sequence of groups. However, you want to simply concatenate those groups. SelectMany is such a concatenation: from a sequence of items, it concatenates the "contents" of each item into one large sequence.