Problem in sort by date in multi array? - c#

I want to sort array A based on values in Array B
actually in Array A I have topics like
keyboard
Laptop
Desktop
mouse
and in Array B i have dates associated with each value in Array A
how i can achieve this....I was thinking of using multi array but i m not sure if there is any default method of sorting multi array ...or if there is any other method to achieve this?

Use:
Array.Sort (A, B, comparer); // comparer can be null here to use the default
where A is the DateTime [] and B is the string [] with A[0] being the date that corresponds to the string B[0] and so on. (MSDN docs here)

Create an object with two properties: a string for your topic and a datetime for your dates. Place those objects in an array or collection and you can then sort on the date and choose to project an array of your topics if you so desire.

If you are managing this completely, you might want to put these into a single class:
class HardwareElement
{
public HardwareElement(string topic, DateTime date)
{
this.Topic = topic;
this.Date = date;
}
public string Topic { get; set; }
public DateTime Date { get; set; }
}
Then, given an array of the above, you can sort these easily:
HardwareElement[] theArray = PopulateMyArray();
Array.Sort(theArray, (l, r) => l.Date.CompareTo(r.Date));

Unless you have a specific reason, you probably shouldn't be storing two associated pieces of data in completely separate arrays.
you could possibly try something like the following:
public enum Device
{
Laptop,
Mouse,
Keyboard
}
public struct DeviceEvent
{
public DeviceEvent(Device device, DateTime timestamp) : this()
{
Device = device;
TimeStamp = timestamp;
}
public Device Device { get; set; }
public DateTime TimeStamp { get; set; }
}
List<DeviceEvent> deviceEvents = new List<DeviceEvent>();
deviceEvents.Add(new DeviceEvent(Device.Keyboard, DateTime.Now);
deviceEvents.Add(new DeviceEvent(Device.Mouse, DateTime.Today);
... etc
IEnumerable<DeviceEvent> orderedDeviceEvents = deviceEvents.OrderBy(e = > e.TimeStamp);

Related

Unity storing an item in c#

so I have 100 items that I need to store in some sort of array.
Each item has an att, def, cost, lvl, name and id(array key) value
What would be the best way to store them, keep in mind that i will need to sort the att and def values in descending order. While I have easily done this with php I am having some trouble with c#.
IF anyone could help provide a working example with just a couple of items that would be great thanks.
I am using unity and c#
Define a structure to store all the attribute:
class Enemy
{
public int Attack { get; set; }
public int Defend { get; set; }
public int Cost { get; set; }
public ....
}
Then store all in a list:
var enemies = new List<Enemy>();
...
You can sort the enemies by anything
var sortedEnemies = enemies.OrderBy(item => item.Attack).ToList();

Sorting multiple arrays c#

currently I'm working on a project where i'm required to sort a total of 6 arrays.
I've managed to sort the arrays individually using a quicksort, however, I'm just wondering if there is a way to sort 1 array and reflect that on the order of elements in the other arrays. For example, if I sort my date array to an ascending order, I want the other arrays to still match up with the dates in respect to the new order.
If possible, could this still be done through a quick sort?
I think the more appropriate option will be to create a new class with all different 6 kind of properties
public class myClass
{
public DateTime date{get;set;}
public string name{get;set;}
//....
}
Then create a single array/list of that class.
public List<myClass> arrData;
Now you can sort that array based on any of your desired property and it will keep the order as per your requirements
arrData.OrderBy(x => x.name)
You can replace x.name with any of your myClass property.
This approach makes your code clean and easy to manage as well.
Likely you have a setup something like this:
DateTime [] dates;
string [] names;
int [] ids;
//...etc
Consider instead to condense your data into a single object, then have a single array of that object:
public class MyObject
{
DateTime date { get; set; }
string name { get; set; }
int id { get; set; }
}
Now you will only have 1 array:
MyObject [] objects;
And you can sort the whole collection of objects by their date:
objects.Sort((a, b) => a.date.CompareTo(b.date));
Also consider using Lists rather than straight arrays, as the use case for using vanilla arrays in c# is very small:
List<MyObject> objects;
It looks like LINQ uses the quick sort algorithm for the OrderBy method (see previous StackOverflow question).
Something like this should take care of it for you:
DateTime[] datesOfBirth = new DateTime[] { new DateTime(1955, 10, 28), new DateTime(1955, 2, 24) };
String[] firstNames = new String[] { "William", "Steve" };
String[] lastNames = new String[] { "Gates", "Jobs" };
var people =
datesOfBirth
.Select((_, i) => new
{
DateOfBirth = datesOfBirth[i],
FirstName = firstNames[i],
LastName = lastNames[i]
})
.OrderBy(x => x.DateOfBirth)
.ToArray();

Sort ArrayList with custom comparison

I am trying to sort an ArrayList using c#. When the ArrayList contains comparable objects, it is possible to sort with using list.Sort() but I need to sort an ArrayList which contains non-comparable objects. For example, let's say the object is Ring and it has an attribute property Price. Then I need to sort the ArrayList to the price order. If is is possible to select ascending or descending that will more helpful. Thank You!
Blockquote
arrAtdMon = **(ArrayList)**hashTb[unixMon];
if (arrAtdMon != null)
monCount = arrAtdMon.Count;
int[] arrayMax = { monCount, tueCount, wedCount, thuCount, friCount };
int maxValue = arrayMax.Max();
KidAttendance valMon = null;
string monTagName = string.Empty;
Blockquote
above array list is to be sorted it self.
You can do this by implementing IComparer interface:-
public class Ring : IComparer
{
public decimal Price { get; set; }
public int Compare(object x, object y)
{
return ((Ring)x).Price.CompareTo(((Ring)y).Price);
}
}
Working Fiddle.
First, you really should be using the List<T> class, not ArrayList. Doing so wouldn't solve your problem, but it would make the code less fragile and more easy to maintain.
As for the specific question, you want to do something like this…
Assume:
class Ring { public decimal Price { get; set; } }
Then:
ArrayList list = ...; // Initialized as some collection of Ring instances
list.Sort(Comparer.Create((r1, r2) => r1.Price.CompareTo(r2.Price)));
This creates a new Comparer instance using the Comparison<T> of (r1, r2) => r1.Price.CompareTo(r2.Price). That is, for each pair of objects being compared, compare the price of the first with the price of the second.
Assuming that these objects share a base class or an interface with the price property you should be able to do something like this:
// Base class with price property, could also be an shared interface
public abstract class Product
{
public decimal Price{get;set;}
}
public class Ring : Product
{
}
public class Bag : Product
{
}
// Some test data
var myUnsortedArray = new Product[]{new Ring{Price = 1.2m}, new Bag{Price=2.5m}};
// Easy sort with LINQ
var sortedProducts = myUnsortedArray.OrderBy(p => p.Price).ToArray();
var sortedProductsDescending = myUnsortedArray.OrderByDescending(p => p.Price).ToArray();
UPDATE
I just realised that the question is about ArrayLists and have the changed solution below:
// Some test data
var myUnsortedArrayList = new ArrayList{new Ring{Price = 1.2m}, new Bag{Price=2.5m}};
// Easy sort with LINQ
var sortedProducts = myUnsortedArrayList.OfType<Product>().OrderBy(p => p.Price).ToArray();
var sortedProductsDescending = myUnsortedArrayList.OfType<Product>().OrderByDescending(p => p.Price).ToArray();
To sort an set of objects, the object needs to be Comparable and you can set up the comparison you'd like in the CompareTo() method:
IComparable information here

How to compare with previous or next element's properties in List<T> while the compare fields are dynamic?

I have a class
class MarketData
{
public double Open {get;set;}
public double High{get;set;}
public double Low{get;set;}
public double Close{get;set;}
}
Now I have created List and filled it with last 30 days data. Here's where I am struggling to find best solution for this. A user can enter conditions manually but in fixed format, the fields can be e.g
Open is Greater Than Previous.Close
High is Less Than Previous.Low
Low is Greater Than Next.High,etc
I am parsing the string conditions to
public enum ConditionComparer { And, Or }
class SimpleCondition
{
public string Operand1 { get; set; }
public Operators Operator { get; set; }
public string Operand2 { get; set; }
public ConditionComparer Compare { get; set; }
}
Now I have to apply this conditions on the List<MarketData> and get matching results.
I used DynamicQueryable class in bit different scenario where conditions where dynamic and it worked perfectly but now I have to compare record with next or previous record.
The problem to get the two MarketData records to compare is a sliding window problem. If you call
var compare = input.Zip(input.Skip(1),
(a,b) => new Tuple<MarketData, MarketData>(a,b));
you get an IEnumerable<Tuple<MarketData, MarketData>> of all pairs of MarketData. Note that your input is enumerated twice.
Using any framework to build dynamic queries, eg. LinqKit, should then do it. Just write expressions that get an Tuple<MarketData, MarketData> as input. The first item in the Tuple is your "older" item, the second is your "newer" item.

What I should use to store a list of assosiated values to be able to retrieve, modify and save one of the elements

I am new to C# and I do not know how to do this
I have a set of associated values
dateValue (string)
valueOne (decimal)
valueTwo (decimal)
I need to be able to pick up the values by a certain date (I could change the dateValue to datetime) and save all the values after modify the valueOne and valueTwo
Should I create a list of objects and loop all the list searching for the proper dateValue which valueOne and valueTwo I want to modify?
What will be the best solution
Create a class, instantiate all the values and then add them to a list?
How could I search for an specific date?
It sounds like a Dictionary may be what you are looking for. A dictionary is a means of storing a Key/value pair and allowing fast and easy lookup of items by key. The key will be dateValue. The Value of the dictionary might be a class that contains valueOne and valueTwo. For example:
var dictionary = new Dictionary<string, Values>();
//Add an item to the dictionary
dictionary.Add("thekey", new Values {ValueOne = 1, ValueTwo = 2});
//Get the item out of the dictionary by key
var values = dictionary["thekey"];
//Update the value of ValueOne for "thekey"
values.ValueOne = 7;
//Print the new value
Console.WriteLine(dictionary["thekey"].ValueOne);
And the class:
public class Values
{
public decimal ValueOne { get; set; }
public decimal ValueTwo { get; set; }
}
As an aside, why not storedateValue as a DateTime rather than a string? This allows you to to have access to various APIs for working with date and time, such as formatting it for display, arithmetic, etc.
In object-oriented programming, you should represent your associated values with a class:
public class MyAssociatedValues // come up with a better name
{
public DateTime Date{get;set;}
public decimal Value1{get;set;} // needs a better name
public decimal Value2{get;set;} // ditto
}
Once you are representing your collection as an IEnumerable<MyAssociatedValues> (this could be a List, an array, or a number of other structures that implement IEnumerable<>), you can easily create a Dictionary to key these values based on their date.
var valuesByDate = values.ToDictionary(v => v.Date);
For easy retrieval by dateValue you could either use a Dictionary with a Tuple containing the two values
Dictionary<string, Tuple<string, string>>
or a Lookup, which is basically a Dictionary that can store a collection of values per key.
I would use a Dictionary to map the DateTime to a structure that contains valueOne and valueTwo.
Something like:
struct Data
{
public decimal valueOne { get; set; }
public decimal valueTwo { get; set; }
}
Dictionary<DateTime, Data> map = new Dictionary<DateTime, Data>();
void addToMap(DateTime dt, decimal one, decimal two)
{
map[dt] = new Data() { valueOne = one, valueTwo = two };
}
Firstly, I would create a class (POCO) instead of a struct unless you have a good reason for a struct.
public class TheClass
{
public DateTime TheDate { get; set; }
public decimal ValueOne { get; set; }
public decimal ValueTwo { get; set; }
}
Secondly, I would store them in any data structure that implements IEnumerable (collection-type) that makes sense. The one that doesn't seem to make sense to me is the one that everyone is suggesting (Dictionary) because it is very much possible that you have 2 objects with the same datetime, so why everyone is suggesting a dictionary baffles me. The only thing I can think of is that they are assuming you only have one pair of values per datetime.
Thirdly, use LINQ to enumerate over the sub-list based on your query.
foreach (var obj in myCollection.Where(item => item.TheDate == requestedDate))
{
//Do whatever you need to do to each enumerated item.
}
Alternatively, if you really want to use the Dictionary instead of LINQ you could create an IDictionary<DateTime, IEnumerable<TheClass>> which means you are caching the collection as the value in the Dictionary.
foreach (var obj in myDictionary[requestedDate])
{
//Do whatever you need to do to each enumerated item.
}

Categories