How can I delete a row which contains null values from a comma separated csv file in c# ?
Example:
| FirstName | LastName | Email | Address |
|---------------------|------------------|---------------|--------------|
| lmn | lmn |lmn#lmn.com |DemoAddress |
| xy | xy |xy#xy.com |DemoAddress |
| demo | demo | | |
| demo2 | demo2 |xy#xy.com |DemoAddress |
Outcome:
| FirstName | LastName | Email | Address |
|---------------------|------------------|---------------|--------------|
| lmn | lmn |lmn#lmn.com |DemoAddress |
| xy | xy |xy#xy.com |DemoAddress |
| demo2 | demo2 |xy#xy.com |DemoAddress |
I tried the following code but doesn't work as expected
private string filterCSV(string strFilePath)
{
var columnIndex = 3;
var line = File.ReadAllLines(strFilePath);
var n = line.Where(x => x[columnIndex].Equals(""));
string result = string.Join("\r", not.ToArray());
return result;
}
Adding answer for future reference
private void RemoveBlanks(string datapath)
{
List<CSV> records;
using (var reader = new StreamReader(datapath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
records = csv.GetRecords<CSV>().ToList();
for(int i = 0; i < records.Count;++i)
{
if (records[i].Email== "" && records[i].Address == "")
{
records.RemoveAt(i);
}
}
}
using (var writer = new StreamWriter(datapath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
}
Related
I have text data that I would like to transfer to json.
I have decided to split them based on '|' an then serialize.
The example below gives the object the same value for each property. I realize that its the iteration however I can't think of a way to do it differently. Could you please share your thoughts?
var test = "Australia | dolar | 1 | AUD | 15,608 | Brasil | real | 1 | BRL 4,016 | Bulgaria | lev | 1 | BGN | 13,066 | China | žen-min-pi | 1 | CNY | 3,369";
var split = test.Split('|');
var list = new List<DailyCourse>();
foreach (var variable in split)
{
var model = new DailyCourse()
{
Country = variable,
Currency = variable,
Amount = variable,
Code = variable,
Course = variable
};
}
list.Add(model);
var json = JsonSerializer.Serialize(list);
Console.WriteLine(json);
the output now is like
[{"Date":null,"Country":"Austr\u00E1lie ","Currency":"Austr\u00E1lie ","Amount":"Austr\u00E1lie ","Code":"Austr\u00E1lie ","Course":"Austr\u00E1lie "}, ...
Your data is in groups of 5, but you are then iterating over each individual element and creating object for each (obviously with the same value in each property).
You need to iterate in steps of 5 and grab the sequence of elements:
var test = "Australia | dolar | 1 | AUD | 15,608 | Brasil | real | 1 | BRL 4,016 | Bulgaria | lev | 1 | BGN | 13,066 | China | žen-min-pi | 1 | CNY | 3,369";
var split = test.Split('|');
for (var i = 0; i < split.Length; i = i + 5)
{
var model = new DailyCourse()
{
Country = split[i];
Currency = split[i + 1];
Amount = split[i + 2];
Code = split[i + 3];
Course = split[i + 4];
}
}
list.Add(model);
var json = JsonSerializer.Serialize(list);
Console.WriteLine(json);
Try this
var test = "Australia | dolar | 1 | AUD | 15,608 | Brasil | real | 1 | BRL| 4,016 | Bulgaria | lev | 1 | BGN | 13,066 | China | žen-min-pi | 1 | CNY | 3,369";
var split = test.Split('|');
var list = new List<DailyCourse>();
var i=0;
while ( i < split.Count())
{
var model = new DailyCourse();
model.Country = split[i]; i++;
model.Currency = split[i]; i++;
model.Amount = Convert.ToInt32( split[i]); i++;
model.Code = split[i]; i++;
model.Course = Convert.ToDouble( split[i]); i++;
list.Add(model);
}
var json = JsonSerializer.Serialize(list);
output
[{"Country":"Australia ","Currency":" dolar ","Amount":1,"Code":" AUD ","Course":15608},
{"Country":" Brasil ","Currency":" real ","Amount":1,"Code":" BRL","Course":4016},
{"Country":" Bulgaria ","Currency":" lev ","Amount":1,"Code":" BGN ","Course":13066},
{"Country":" China ","Currency":" \u017Een-min-pi ","Amount":1,"Code":" CNY ","Course":3369}]
class
public class DailyCourse
{
public string Country { get; set; }
public string Currency { get; set; }
public int Amount { get; set; }
public string Code { get; set; }
public double Course { get; set; }
}
i have odd problem . i ma trying to iterate bd Table with 5 row and return this table value + an image as string , well when i check foreach loop all item passed and add to object list but when it's time to return all value i found 5 same value in list item !!! all belong to last table row ?
public class TransferItem
{
public string foodType { set; get; }
public string foodName { set; get; }
public int foodPrice { set; get; }
public string foodDescription { set; get; }
public byte[] foodImage { set; get; }
}
var Transfer = new transferToFront();
var mylist = new List<object>();
foreach (var obj in FoodObjt)
{
String filePath = HostingEnvironment.MapPath(#"~/Images/");
Transfer.Id = obj.Id;
Transfer.foodName = obj.foodName;
Transfer.foodImage = obj.foodImage;
Transfer.foodPrice = obj.foodPrice;
Transfer.foodType = obj.foodType;
Transfer.foodDescription = obj.foodDescription;
var imageString = System.IO.File.ReadAllBytes(filePath + obj.foodImage);
Transfer.Image = imageString;
mylist.Add(Transfer);
}
return Ok(mylist);
result of iteration
Transfer is shared across iterations of the loop, and thus each time you append the same object to the list. The memory map looks like:
+--------------------------+
| Transfer |
+--+----+----+----+---+----+
| | | | |
+--+----+----+----+---+--+
| 0 1 2 3 4 |
| myList |
+------------------------+
So when you change Transfer, you change all of the items in the list - because the're same.
The solution is to create a fresh new instance for each iteration:
var mylist = new List<object>();
foreach (var obj in FoodObjt)
{
var Transfer = new transferToFront();
String filePath = HostingEnvironment.MapPath(#"~/Images/");
Transfer.Id = obj.Id;
Transfer.foodName = obj.foodName;
Transfer.foodImage = obj.foodImage;
Transfer.foodPrice = obj.foodPrice;
Transfer.foodType = obj.foodType;
Transfer.foodDescription = obj.foodDescription;
var imageString = System.IO.File.ReadAllBytes(filePath + obj.foodImage);
Transfer.Image = imageString;
mylist.Add(Transfer);
}
return Ok(mylist);
Now the memory map looks like:
+----------+ +----------+ +----------+ +----------+ +----------+
|Transfer 1| |Transfer 2| |Transfer 3| |Transfer 4| |Transfer 5|
+--+-------+ +-----+----+ +---+------+ +----+-----+ +---+------+
| | | | |
| +----------+ | | |
| | +----------------+ | |
| | | +-------------------------+ |
| | | | +---------------------------------+
| | | | |
+--+----+----+----+---+--+
| 0 1 2 3 4 |
| myList |
+------------------------+
I'm using SSIS to export from Excel to text and in my case, I need to export where the file contains merged columns anyone can help or have suggest for my case?
Input Excel
A B C D E
+-------------+-----------------+-----------------+
| Shop Name | Monday | Tuesday |
| +---------+-------+---------+-------+
| | Jackson | Steve | Jackson | Steve |
+-------------+---------+-------+---------+-------+
| 7Eleven | 11 | 30 | 23 | 21 |
+-------------+---------+-------+---------+-------+
| Delta Shop | 43 | 12 | 33 | 2 |
+-------------+---------+-------+---------+-------+
Output Expected
+-------------+---------+-------------+-------+
| Shop_Name | Day | Member_Name | Point |
+-------------+---------+-------------+-------+
| 7Eleven | Monday | Jackson | 11 |
+-------------+---------+-------------+-------+
| 7Eleven | Monday | Steve | 30 |
+-------------+---------+-------------+-------+
| Delta Shop | Monday | Jackson | 43 |
+-------------+---------+-------------+-------+
| Delta Shop | Monday | Steve | 12 |
+-------------+---------+-------------+-------+
| 7Eleven | Tuesday | Jackson | 23 |
+-------------+---------+-------------+-------+
| 7Eleven | Tuesday | Steve | 21 |
+-------------+---------+-------------+-------+
| Delta Shop | Tuesday | Jackson | 33 |
+-------------+---------+-------------+-------+
| Delta Shop | Tuesday | Steve | 2 |
+-------------+---------+-------------+-------+
Using oledb and ACE driver (Microsoft Office) to read excel file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;
namespace ConsoleApplication124
{
class Program
{
static void Main(string[] args)
{
string connStr = "Provider=Microsoft.ACE.OLEDB.15.0;Data Source=c:\\temp\\test.xlsx;Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"";
string query = "Select * From [Sheet1$]";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, connStr);
DataTable dt = new DataTable();
adapter.Fill(dt);
string[] days = dt.Rows[0].ItemArray.Skip(1).Select(x => (x == DBNull.Value) ? string.Empty : ((string)x).Trim()).ToArray();
string[] people = dt.Rows[1].ItemArray.Skip(1).Select(x => (x == DBNull.Value) ? string.Empty : ((string)x).Trim()).ToArray();
int numberDays = days.Where(x => x != string.Empty).Count();
int numberPeople = people.Where(x => x != string.Empty).Distinct().Count();
string[] columnNames = { "Shop_Name", "Day", "Member_Name", "Point" };
Console.WriteLine(string.Join(",", columnNames));
for (int row = 2; row < dt.Rows.Count; row++)
{
string[] columns = dt.Rows[row].ItemArray.Select(x => (x == DBNull.Value) ? string.Empty : ((string)x).Trim()).ToArray();
string shop = columns[0];
for (int col = 1; col < dt.Rows[row].ItemArray.Count(); col++)
{
object point = dt.Rows[row].Field<string>(col);
if (point != null)
{
string pointStr = ((string)point).Trim();
int dayIndex = numberPeople * ((col - 1) / numberPeople);
string day = days[dayIndex];
string person = people[col - 1];
string[] outputData = { shop, day, person, pointStr };
Console.WriteLine(string.Join(",", outputData));
}
}
}
Console.ReadLine();
}
}
}
I have two tables called tableFileTemp2 and tableFile. I need a distinct list of computers merging the path and file columns into tableFile tables path column...
tableFileTemp2 //source
+-------+----------+--------+-------+
| host | path | date | file |
+-------+----------+--------+-------+
| comp1 | c:\ | xydate | x.exe |
| comp1 | c:\Temp\ | xydate | x.exe |
| comp2 | c:\win\ | xydate | y.exe |
| comp2 | c:\win\ | xydate | z.exe |
+-------+----------+--------+-------+
tableFile //this is the result, apparently the first path+file is being duplicated for each machine
+-------+---------------------------------------------------+--------+------+
| host | path | date | file |
+-------+---------------------------------------------------+--------+------+
| comp1 | c:\x.exe<br>c:\x.exe<br>c:\Temp\x.exe<br> | xydate | null |
| comp2 | c:\win\y.exe<br>c:\win\y.exe<br>c:\win\z.exe<br> | xydate | null |
+-------+---------------------------------------------------+--------+------+
tableFile //expected result
+-------+----------------------------------+--------+------+
| host | path | date | file |
+-------+----------------------------------+--------+------+
| comp1 | c:\x.exe<br>c:\Temp\x.exe<br> | xydate | null |
| comp2 | c:\win\y.exe<br>c:\win\z.exe<br> | xydate | null |
+-------+----------------------------------+--------+------+
my code:
for (int s = 0; s < tableFileTemp2.Rows.Count; s++)
{
if (tableFile.Rows.Count != 0)
{
for (int t = 0; t < tableFile.Rows.Count; t++)
{
if (string.Equals(tableFile.Rows[t][0].ToString(), tableFileTemp2.Rows[s][0].ToString(), StringComparison.OrdinalIgnoreCase))
{
tableFile.Rows[t][1] = tableFile.Rows[t][1].ToString() + tableFileTemp2.Rows[s][1].ToString() + tableFileTemp2.Rows[s][3].ToString() + "<br>";
break;
}
else if (t == (tableFile.Rows.Count - 1))
{
tableFile.Rows.Add(tableFileTemp2.Rows[s][0].ToString(), (tableFileTemp2.Rows[s][1].ToString() + tableFileTemp2.Rows[s][3].ToString() + "<br>"), tableFileTemp2.Rows[s][2], null);
}
}
}
else
{
tableFile.Rows.Add(tableFileTemp2.Rows[s][0].ToString(), (tableFileTemp2.Rows[s][1].ToString() + tableFileTemp2.Rows[s][3].ToString() + "<br>"), tableFileTemp2.Rows[s][2], null);
}
}
As you say in your comment that you still have the original CSV that the data came from. We can do this with LINQ.
+-------+----------+--------+-------+
| host | path | date | file |
+-------+----------+--------+-------+
| comp1 | c:\ | xydate | x.exe |
| comp1 | c:\Temp\ | xydate | x.exe |
| comp2 | c:\win\ | xydate | y.exe |
| comp2 | c:\win\ | xydate | z.exe |
+-------+----------+--------+-------+
Then the code looks like.
var results =
from thing in
(from line in tableFileCSV.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)
let row = line.Split(',')
select new
{
Host = row[0],
Path = row[1] + row[3] + "</br>",
Date = row[2],
File = row[3] // <- Are you sure you want this to be null and not the file value?
})
group new { thing.Path, thing.Date, thing.File } by new { thing.Host } into g
select new
{
Host = g.Key.Host,
Path = g.Select(i => i.Path).Aggregate((a, b) => a + b),
Date = g.Select(i => i.Date).FirstOrDefault(),
File = "File",
};
// If you want to get a look at it.
foreach (var item in results)
{
Console.WriteLine("{0} {1} {2} {3}", item.Host, item.Path, item.Date, item.File);
}
Where the tableFileCSV is your original data in a CSV.
This can then be passed into a datatable.
var dt = new DataTable();
dt.Columns.Add("Host");
dt.Columns.Add("Path");
dt.Columns.Add("Date");
dt.Columns.Add("File");
foreach (var item in results)
{
dt.Rows.Add(item.Host,item.Path,item.Date,item.File);
}
Im trying to read records from a database using Entity Framework , which I have not used before.
Im trying to run the load rule method:
class Rule
{
private STRATCODE stratCode;
private STRATRULEDEF stratRuleDef;
AREEntities AREDb = new AREEntities();
public Rule(STRATRULEDEF StratRuleDef, STRATCODE StratCode)
{
this.stratRuleDef = StratRuleDef;
this.stratCode = StratCode;
}
public void LoadRule()
{
var query = from stratCode in AREDb.STRATCODES
where stratCode.CODEVALUE == "49300"
select stratCode;
//StratCodeRepository StratCodeRepository = new StratCodeRepository(new AREEntities());
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\user\Desktop\NewText.txt",true))
{
foreach (STRATCODE row in query)
{
file.WriteLine("{0} | {1} | {2} | {3} | {4} | {5}", stratCode.STRATRULEKEY, stratCode.CODETYPE, stratCode.CODEVALUE, stratCode.SYSTEMID, stratCode.CODESETKEY, stratCode.PAYMENTYEAR);
}
}
}
My problem is that everytime I run it, it returns the right number of records but all of the data in the text file is empty and I can find no clues in my output log.
0 | | | | |
0 | | | | |
0 | | | | |
0 | | | | |
0 | | | | |
Any ideas? I dont know how to even start with no clues
Your write is not using the foreach variable:
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\stephen.carmody\Desktop\NewText.txt", true))
{
foreach (var row in query)
{
file.WriteLine("{0} | {1} | {2} | {3} | {4} | {5}",
row.STRATRULEKEY,
row.CODETYPE,
row.CODEVALUE,
row.SYSTEMID,
row.CODESETKEY,
row.PAYMENTYEAR);
}
}