0

Code:

while ((linevalue = filereader.ReadLine()) != null)
{
 items.Add(linevalue);
}
filereader.Close();
items.Sort();
//To display the content of array (sorted)
IEnumerator myEnumerator = items.GetEnumerator();
while (myEnumerator.MoveNext())
{
 Console.WriteLine(myEnumerator.Current);
}

The program above displays all the values. How to extract only the dates and sort it in ascending order?


I am not let to work with linq, use the exception or threading or any other stuff. I have to stick with the File Stream, try to get my data out of the text file, sort and store it, so that i can retrieve it, view it and edit it and search for any particular date and see the date of joining records for that date. Can't figure out. Struggling

asked Jul 30, 2013 at 9:09
6
  • 4
    Why do you use an arraylist at all nowadays? Why don't you simply use File.ReadAllLines instead which returns a String[]? Even better, load a List<CustomClass> where CustomClass has the properties above. Commented Jul 30, 2013 at 9:13
  • Are the "columns" in the text file delimited (e.g. tab)? Commented Jul 30, 2013 at 9:14
  • 1
    Also, don't use the enumerator directly, use foreach instead: foreach(var item in items) Console.WriteLine(item); Commented Jul 30, 2013 at 9:17
  • to emphasize @digEmAll's point - in addition to being extra code, you've actually not implemented it fully - technically, you also need to check if myEnumerator is IDisposable, and if so ensure you dispose it (for both success and failure) - foreach does a lot of good things for you. Additionally, foreach supports duck-typing, meaning: it can be more efficient than IEnumerator Commented Jul 30, 2013 at 9:29
  • No, its not like a tab. Commented Jul 30, 2013 at 9:32

4 Answers 4

4

Basically, don't try and work with the file as lines of text; separate that away, so that you have one piece of code which parses that text into typed records, and then process those upstream when you only need to deal with typed data.

For example (and here I'm assuming that the file is tab-delimited, but you could change it to be column indexed instead easily enough); look at how little work my Main method needs to do to work with the data:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
static class Program
{
 static void Main()
 {
 foreach (var item in ReadFile("my.txt").OrderBy(x => x.Joined))
 {
 Console.WriteLine(item.Names);
 }
 }
 static readonly char[] tab = { '\t' };
 class Foo
 {
 public string Names { get; set; }
 public int Age { get; set; }
 public string Designation { get; set; }
 public DateTime Joined { get; set; }
 }
 static IEnumerable<Foo> ReadFile(string path)
 {
 using (var reader = File.OpenText(path))
 {
 // skip the first line (headers), or exit
 if (reader.ReadLine() == null) yield break;
 // read each line
 string line;
 var culture = CultureInfo.InvariantCulture;
 while ((line = reader.ReadLine()) != null)
 {
 var parts = line.Split(tab);
 yield return new Foo
 {
 Names = parts[0],
 Age = int.Parse(parts[1], culture),
 Designation = parts[2],
 Joined = DateTime.Parse(parts[3], culture)
 };
 }
 }
 }
}

And here's a version (not quite as elegant, but working) that works on .NET 2.0 (and probably on .NET 1.1) using only ISO-1 language features; personally I think it would be silly to use .NET 1.1, and if you are using .NET 2.0, then List<T> would be vastly preferable to ArrayList. But this is "worst case":

using System;
using System.Collections;
using System.Globalization;
using System.IO;
class Program
{
 static void Main()
 {
 ArrayList items = ReadFile("my.txt");
 items.Sort(FooByDateComparer.Default);
 foreach (Foo item in items)
 {
 Console.WriteLine(item.Names);
 }
 }
 class FooByDateComparer : IComparer
 {
 public static readonly FooByDateComparer Default
 = new FooByDateComparer();
 private FooByDateComparer() { }
 public int Compare(object x, object y)
 {
 return ((Foo)x).Joined.CompareTo(((Foo)y).Joined);
 }
 }
 static readonly char[] tab = { '\t' };
 class Foo
 {
 private string names, designation;
 private int age;
 private DateTime joined;
 public string Names { get { return names; } set { names = value; } }
 public int Age { get { return age; } set { age = value; } }
 public string Designation { get { return designation; } set { designation = value; } }
 public DateTime Joined { get { return joined; } set { joined = value; } }
 }
 static ArrayList ReadFile(string path)
 {
 ArrayList items = new ArrayList();
 using (StreamReader reader = File.OpenText(path))
 {
 // skip the first line (headers), or exit
 if (reader.ReadLine() == null) return items;
 // read each line
 string line;
 CultureInfo culture = CultureInfo.InvariantCulture;
 while ((line = reader.ReadLine()) != null)
 {
 string[] parts = line.Split(tab);
 Foo foo = new Foo();
 foo.Names = parts[0];
 foo.Age = int.Parse(parts[1], culture);
 foo.Designation = parts[2];
 foo.Joined = DateTime.Parse(parts[3], culture);
 items.Add(foo);
 }
 }
 return items;
 }
}
answered Jul 30, 2013 at 9:25

8 Comments

public string Names { get; set; } public int Age { get; set; } public string Designation { get; set; } public DateTime Joined { get; set; }
@MartinSahner er... yes?
It generates an error stating that the get and set methods are not marked extern or abstract and hence should declare a body.
@MartinSahner and as I already replied elsewhere: please tell us what version of Visual Studio you are using, as that suggests you are using a really really old version of C#. I have, however, edited in a second version that should work just about anywhere.
@MartinSahner I can't tell if that question is serious... the job of the compiler is to check whether something is syntactically valid, and if so : compile it into IL (in the case of .NET); it might also give you some warnings if it spots obvious errors (trying to use an object that can only possibly be null, etc). What it doesn't do is check that you've written the right thing. Most likely, your file is not, in fact, tab-delimited - in which case you'll need to change the code to parse it by column index instead. Use the debugger; press F5 and watch what it does.
|
0

I'm not sure why you'd want to retrieve just the dates. You'd probably be better reading your data into Tuples first. Something like

List<Tuple<string, int, string, DateTime>> items. 

Then you can sort them by items.Item4, which will be the date.

answered Jul 30, 2013 at 9:21

Comments

0

You can use LINQ and split the line according to tabs to only retrieve the date and order them through a conversion to date.

while ((linevalue = filereader.ReadLine()) != null)
 {
 items.Add(linevalue.Split('\t').Last());
 }
 filereader.Close();
 items.OrderBy(i => DateTime.Parse(i));
 foreach(var item in items)
 {
 Console.WriteLine(item);
 }
answered Jul 30, 2013 at 9:25

2 Comments

public string Names { get; set; } public int Age { get; set; } public string Designation { get; set; } public DateTime Joined { get; set; } this does not work for me as it keeps stating that i need to declare a body for the get and set methods are not marked abstract or extern
@MartinSahner I suspect that was intended for my post; that suggests you are using a very old version of C# - what version of Visual Studio are you using, so that we can give an appropriate answer?
0

get the desired values in Array from the file...

public class DateComparer : IComparer {
 public int Compare(DateTime x, DateTime y) {
 if(x.Date > y.Date)
 return 1;
 if(x.Date < y.Date)
 return -1;
 else
 return 0;
 }
}
list.Sort(new DateComparer());
answered Jul 30, 2013 at 9:25

1 Comment

you realise that comparer is malformed? it needs to handle all 3 cases... besides - return x.CompareTo(y); or return y.CompareTo(x); would be saner. Not to mention that the code doesn't have DateTimes

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.