Sort Multi Dimensional/Jagged Array from Api - c#

I need a little help beyond what I have found on stack so far.
I have an array that looks like this (First is this Multi Dimensional or Jagged?)
Second I would like to Sort this by the Start Date which is [X][4]
I have tried several searches and saw the below which I tired
//string[][] SenorityList = SalesEmployees.OrderBy(inner => inner[0][4]).ToArray();
But I dont really understand how it works so cant make it work...
I also saw http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=151 which looks like it may work by using a class but again not understanding it so not sure how to deploy it for my needs.
Below I have added the export I am using that builds the array so you can see the variable names etc.
#region GrabSalesEmployees
DateTime Now = DateTime.Now;
EP203000Content EP203000 = context.EP203000GetSchema();
context.EP203000Clear();
string[][] SalesEmployees;
SalesEmployees = context.EP203000Export(
new Command[] {
EP203000.EmployeeInfo.ServiceCommands.EveryEmployeeID,
EP203000.GeneralInfoEmployeeSettings.EmployeeClass,
EP203000.EmployeeInfo.Status,
EP203000.EmployeeInfo.EmployeeID,
EP203000.EmploymentHistory.Position,
EP203000.EmploymentHistory.StartDate,
EP203000.EmploymentHistory.EndDate
},
new Filter[] {
new Filter { Field = new Field { FieldName = EP203000.GeneralInfoEmployeeSettings.EmployeeClass.FieldName }, Condition = FilterCondition.Equals, Value = "SALES", Operator = FilterOperator.And },
new Filter { Field = new Field { FieldName = EP203000.EmployeeInfo.Status.FieldName }, Condition = FilterCondition.Equals, Value = "Active", Operator = FilterOperator.And },
new Filter { Field = new Field { FieldName = EP203000.EmployeeInfo.EmployeeID.FieldName }, Condition = FilterCondition.NotEqual, Value = "BA00000450", Operator = FilterOperator.And },
},
0, false, false
);

Jagged array is an array of arrays. If you are sure that every inner array contains date in the 4th element you can use next code:
// for each element of external array (1st dimension) order by 4th element of jagged (2nd dimension) by ascending
string[][] SenorityList = SalesEmployees.OrderBy(innerArray => innerArray[4]).ToArray();
Of course the better way is to check elements and cast them to DateTime:
string[][] SenorityList = SalesEmployees.OrderBy(innerArray =>
{
if (innerArray.Length >= 5)
{
DateTime startDate;
if (DateTime.TryParse(innerArray[4], out startDate))
return startDate;
}
// if you want that unpasrsed dates will be on the end of the list use DateTime.MaxValue
return DateTime.MaxValue;
}).ToArray();

Related

MongoDB/ - Update Multiple Fields inside an array, keep their original value, but update datatype

So the problem I have is that I want to be able to filter on a particular criteria.
I originally tried to filter based on the datatype of the field, I am struggling to do this with arrays though. This did work at one point with single fields, but now not having much joy.
Then as part of the update I want to set specific fields inside the array from string datatype to say integer.
So to summarise I want to do the following:
Filter where the fields in the array are string datatype as I want to update them.
Update only the datatype and retain the value(essentially converting from string to integer)
Get results with modified count to ensure it was successful.
Thanks in advance.
var mongoDb = mongoClient.GetDatabase(config.DatabaseName); // , new MongoDatabaseSettings() { WriteConcern = WriteConcern.Unacknowledged }
var objectId = new ObjectId("63d38c71ef08fde3fbf1b9da");
var filter = Builders<BsonDocument>.Filter.Eq("_id", objectId);
var updateQuery = new BsonDocument { { "$set", new BsonDocument { { "CheckFinalization.Check.ItemDetail.$[].ItemNumber", new BsonDocument { { "$toInt", "$CheckFinalization.Check.ItemDetail.$[].ItemNumber" } } } } } };
var updatePipeline = Builders<BsonDocument>.Update.Pipeline(PipelineDefinition<BsonDocument, BsonDocument>.Create(updateQuery));
var dataCollection = mongoDb.GetCollection<BsonDocument>(config.CollectionName);
var recordResult = dataCollection.Find(filter).Limit(100).ToList();
// check we have records to update.
if (recordResult.Any())
{
var result = dataCollection.UpdateMany(filter, updatePipeline);
if (result.ModifiedCount > 0)
{
// Success
}
else
{
// Failed
}
}`

Using linq with string split

workareaRefs is a string of random values splitted by comma i.e. 4,7,1,7 etc.
I am setting properties to TrackDataFilter and would like to set the Workareas
which is of type IList with the values in workareaRefs var.
So Workareas should contain the values in workareaRefs stored in the variable named r.
Can anyone help me achieve this?
var workareasRefs = workareaRefs.Split(',');
var r = new TrackDataFilter
{
DatePreset = preset,
Workareas = new List<TrackFilterGenericRef>
{
new TrackFilterGenericRef
{
Ref = 2, Type = Enums.ContentTypes.Workarea
}
},
};
Well, I am not sure If I understand your question correctly, so by guessing a bit, I would assume you want to do the following
WorkAreas = new List(workareasRefs);

Querying a list of strings with a query string?

I have a dictionary:
<string,List<string>>
The key is the product code say "product1" then the list is a list of properties:
"Brand","10.40","64","red","S"
Then I 'can' have a list of rules/filters e.g.
var tmpFilter = new customfilters();
tmpFilter.Field = "2";
tmpFilter.Expression = ">";
tmpFilter.Filter = "10";
So for the above example this would pass because at index 2 (tmpFilter.Field) it is more than 10; then I have another object which defines which fields within the list I want to write to file. For that dictionary item I just want to write the product brand and price where the filters match.
At the moment without the filter I have:
var tmp = new custom();
tmp.Columns = "0,1";
tmp.Delimiter = ",";
tmp.Extention = ".csv";
tmp.CustomFilters = new List<customfilters>() {new customfilters(){ Field = "2", Expression = ">", Filter = "10"} };
public static void Custom(custom custom)
{
foreach (var x in Settings.Prods)
{
//Get Current Product Code
var curprod = Settings.ProductInformation[x];// the dictionary value
foreach (var column in custom.Columns)
{
var curVal = curprod[Convert.ToInt32(column)];
tsw.Write(curVal + custom.Delimiter);
}
Settings.Lines++;
tsw.WriteLine();
}
tsw.Close();
}
I only want to write the curprod if all the filters pass for that list of strings.
How I can do this?
There's a really nice Nuget package based on an example published by Microsoft, that they have decided to make really hard to find for some reason, that allows dynamic linq queries:
https://www.nuget.org/packages/System.Linq.Dynamic/1.0.2
Source:
https://github.com/kahanu/System.Linq.Dynamic
Using that you can do stuff like this very easily (note: I used strings here because the OP states they have a List<string>):
List<string> stuff = new List<string> { "10.40", "64", "5", "56", "99", "2" };
var selected = stuff.Select(s => new { d = double.Parse(s) }).Where("d > 10");
Console.WriteLine(string.Join(", ", selected.Select(s => s.d.ToString()).ToArray()));
Outputs:
10.4, 64, 56, 99
That may give you a place to start. One thing you are going to have to tackle is identifying which of your fields are numeric and should be converted to a numeric type before trying to apply your filter. Otherwise you are going to comparing as strings.

Store each parsed value of JSON into an array

I'm working on the Array in C#, as following code below, the uricontent is a List in which each string contains one JSON value, I could parse the content, however, I want to have one other array or List to store each parsed value, in the example below, rooms variable can store each time one JSON parsed value, now I wish to store those parsed values in one array.
int i = 0;
while (uricontent.Count != 0)
{
var rooms = JObject.Parse(uricontent[i].ToString())
["rooms"]
.Select(x => new
{
roomID = (string)x["room_name"],
Name = WebUtility.HtmlDecode((string)x["room_name"]),
Price = PriceHelper.Convert((string)x["discountedTotal"]),
Currency = (string)x["currency"],
Occupan = (int)x["adult"]
}).ToArray();
i++;
}
rooms {<>f_AnonymousType11[1]<>f_AnonymousType11[]
[0] { roomID = "Superior 1st floor", Name = "Superior 1st floor", Price = 207.4, Currency = "EUR", Occupan = 2 }
As indicating above, the rooms overwrite the data in each iteration, how can I store those values in one other array like
[1].....
[2].....
....
Thanks
I think what you need is the SelectMany method. SelectMany concatenates all of the IEnumerables generated by the inner Select statements, and returns them as a single IEnumerable, which can then be converted into an array:
var rooms = uricontent
.SelectMany(
uriContentElementJson =>
{
JObject uriContentElement = JObject.Parse(uriContentElementJson);
return uriContentElement["rooms"].Select(
room => new
{
RoomID = (string)room["room_name"],
Name = WebUtility.HtmlDecode((string)room["room_name"]),
Price = PriceHelper.Convert((string)room["discountedTotal"]),
Currency = (string)room["currency"],
Occupant = (int)room["adult"]
});
})
.ToArray();

Need a Recursive Function to Solve a Typical Ecommerce Multi-Variation Problem

Let's say I have the following data (in pseudo-code for readability):
var myVariations = [
{ Name = "Color", Values = ["Red", "Yellow", "Green" /*, etc. */] },
{ Name = "Size", Values = ["S", "M", "L" /*, etc. */] },
{ Name = "Length", Values = ["34", "35", "36" /*, etc. */] },
/* and so on...(up to 5 total) */
];
And I can get that data with LINQ like so:
var myVariations = myProduct.Variations.ToList();
How can I go about mapping those variations into a structure like this (for the eBay Trading API):
var ebayVariations = [
{
Name = "Red-S-34",
Value = [
// yes, these are arrays with only one item
{ Name = "Color", Values = [{Value = "Red"}] },
{ Name = "Size", Values = [{Value = "S"}] },
{ Name = "Length", Values = [{Value = "34" }] }
]
},
/* etc for all possible combinations */
];
Obviously the fact that the Values array holds only one value is a bit strange; but with eBay's Trading API if I list multiple values in a single Variation (which is easy to do compared to this recursive stuff) it complains. So alternatively, if you are familiar with the eBay Trading API, how can I get this to work in an "optimal" fashion, in-line with the way eBay intended Variations to be listed (called via AddFixedPricedItem, if you care).
I don't know anything about the eBay Trading API, but here's an article on computing a Cartesian Product with LINQ (the very last step drops the recursion in favor of aggregation).
I've changed terminology insignificantly, but wrote clarifying comments.
public IEnumerable<Combination> GetCombinations(Variation[] variations, int variationIndex, IEnumerable<VariationPosition> aggregatedPositions)
{
// We should choose one position from every variation,
// so we couldn't produce combination till we reach end of array.
if (variationIndex < variations.Length)
{
// Pick current variation.
var currentVariation = variations[variationIndex];
// Every variation has list of possible positions (Color could be Green, Redm, Blue, etc.).
// So we should walk through all the positions
foreach (var val in currentVariation.Positions)
{
// Current position. Variation's name will be used during creating result Combination.
var position = new VariationPosition()
{
Name = currentVariation.Name,
Value = val
};
// Add position to already aggregated on upper levels of recursion positions.
var newPositions = aggregatedPositions.Concat(Enumerable.Repeat(position, 1));
// So we picked some variation position
// Let's go deeper.
var combinations = this.GetCombinations(variations, variationIndex + 1, newPositions );
// This piece of code allows us return combinations in iterator fashion.
foreach (var combination in combinations)
{
yield return combination;
}
}
}
else
{
// We reached end of variations array
// I mean we have one position of every variation.
// We concatenate name of positions in order to create string like "Red-S-34"
var name = aggregatedPositions.Aggregate("", (res, v) => res += v.Name);
// This code is a little bit naive, I'm too lazy to create proper infrastructure,
// But its mission is to create content for property Value of your ebayVariations item.
var value = aggregatedPositions
.Select(v => new { Name = v.Name, Values = new[] { new { Value = v.Value } } })
.ToArray();
// And we return completed combination.
yield return new Combination()
{
Name = name,
Value = value,
};
}
}
And usage:
var allCombinations = this.GetCombinations(inputVariations, 0, new VariationPosition[0]).ToArray();

Categories