Advanced table sorting in lua - sorting

I am attempting to sort an advanced table, but not succeeding.
Here is what my table structure looks like:
{
["12345"] = {12345, "Something", {"Stuff"}},
["523544"] = {523544, "Something", {"Stuff"}},
["6744"] = {6744, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["724572"] = {724572, "Something", {"Stuff"}},
["54"] = {54, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["12345"] = {12345, "Something", {"Stuff"}},
["44"] = {44, "Something", {"Stuff"}},
}
and I would like to sort it from greatest to least like so:
{
["724572"] = {724572, "Something", {"Stuff"}},
["523544"] = {523544, "Something", {"Stuff"}},
["12345"] = {12345, "Something", {"Stuff"}},
["12345"] = {12345, "Something", {"Stuff"}},
["6744"] = {6744, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["54"] = {54, "Something", {"Stuff"}},
["44"] = {44, "Something", {"Stuff"}},
}
I am running into a few problems here.
It can't save 2 numbers of equal value
I can't seem to sort it properly from greatest to least
As for why the indexes are strings, if I do table[623258195] = "Example", the table would create 623258195 indexes, causing my program to crash.
As for why the values are tables, it stores other important information, which is what the 2nd and 3rd values in the table are, the 1st being an number form of the index.
I hope I'm being clear, and I'm sorry if this would be considered a duplicate question, I have not found anything in the last hour of searching that has assisted me.

You'll need to modify your data structure, to support multiple values with the same id/key:
{
[12345] = {
{12345, "foo", {"bar"}}, -- You'll probably want to sort these somehow.
{12345, "baz", {"qux"}}
},
[123] = {
{123, "foo", {"bar"}}
}
}
You can use table.sort(tbl, f), along with an index table:
local unsorted = {} -- Data, in your format, inside this table.
local index = {} -- Table which will contain sorted keys (then you loop over this, get unsorted[k])
for k in pairs(unsorted) do
index[#index+1] = k -- Populate the keys to sort.
end
table.sort(index, function(a, b)
return b < a -- Order highest to lowest, instead of lowest - highest (default)
end)
Here's the full code sample, and results. http://ideone.com/thE1zP

You can't "sort" keys in a hash as they don't have "order" in the way the integer sequence of keys in a table does.
You can change the data structure to turn the hash into a table, but an easier way may be to have a separate table with just the hash keys and sort their values; when you need to get the elements from the hash in a particular order, you simply go through the (sorted) elements in that table and then retrieve the elements from the hash.
In either case you won't be able to store multiple values for the same key as you are attempting to do:
{
...
["146"] = {146, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
["146"] = {146, "Something", {"Stuff"}},
...
}
You need to store them in a table (and reference that table using "146" key) or rethink why you need different elements keys by the same key value.

Related

Name of sorting algorithm?

I'm trying to figure out the name of a sorting algorithm (or just a method?) that sorts via 3 values.
We start off with 3 values and the array should sort based on the id of the object, position and then the date it was set to that position, allowing both date and position to be the same. Please excuse my horrible explanation. I will give an example.
we have 6 positions, without any edits the array would look something like this
{id:1,pos:0,date:0}
{id:2,pos:0,date:0}
{id:3,pos:0,date:0}
{id:4,pos:0,date:0}
{id:5,pos:0,date:0}
{id:6,pos:0,date:0}
if I was to move the first object to the second position, it would return this order
{id:2,pos:0,date:0}
{id:1,pos:2,date:1}
{id:3,pos:0,date:0}
{id:4,pos:0,date:0}
{id:5,pos:0,date:0}
{id:6,pos:0,date:0}
However if we where to then move the third object into the second position
{id:2,pos:0,date:0}
{id:3,pos:2,date:2}
{id:1,pos:2,date:1}
{id:4,pos:0,date:0}
{id:5,pos:0,date:0}
{id:6,pos:0,date:0}
Note the pos does not change but is ordered before positions of the same number based on the higher date value.
We now move the 4th object into position 1
{id:4,pos:1,date:3}
{id:2,pos:0,date:0}
{id:3,pos:2,date:2}
{id:1,pos:2,date:1}
{id:5,pos:0,date:0}
{id:6,pos:0,date:0}
note id 2 takes the position of number 2 even though pos and date are still 0 because the id is less than the id behind it
We now move id 6 to position 2
{id:4,pos:1,date:3}
{id:6,pos:2,date:4}
{id:2,pos:0,date:0}
{id:3,pos:2,date:2}
{id:1,pos:2,date:1}
{id:5,pos:0,date:0}
id 5 to position 4
{id:4,pos:1,date:3}
{id:6,pos:2,date:4}
{id:2,pos:0,date:0}
{id:5,pos:4,date:5}
{id:3,pos:2,date:2}
{id:1,pos:2,date:1}
And finally id 2 to position 6
{id:4,pos:1,date:3}
{id:6,pos:2,date:4}
{id:5,pos:4,date:5}
{id:3,pos:2,date:2}
{id:1,pos:2,date:1}
{id:2,pos:6,date:6}
I hope my examples aid any response given, I know this is not a question of much quality and if answered I will do my best to edit the question as best I can.
Just a guess, because your final order doesn't look "sorted", lexicographical sort? See Lexicographical order.
The movement of objects is similar to insertion sort, where an entire sub-array is shifted in order to insert an object. The date indicates the order of operations that were performed, and the position indicates where the object was moved to, but there's no field for where an object was moved from. There's enough information to reproduce the sequence by starting with the initial ordering and following the moves according to the date. I don't know if the sequence can be followed in reverse with the given information.
The original ordering can be restored using any sort algorithm using the id field.
I was unfortunately unable to find the name of the 'sort'(?) however, I was able to achieve the effect I was aiming for using the code bellow.
(If I missed something entirely let me know I'll change it and credit you)
PHP Implementation.
$data = '[
{"id":"1","pos":"1","date":"0"},
{"id":"2","pos":"5","date":"0"},
{"id":"3","pos":"4","date":"0"},
{"id":"4","pos":"3","date":"0"},
{"id":"5","pos":"4","date":"1"},
{"id":"6","pos":"2","date":"0"}
]'; //simulated data set
$arr = json_decode($data,true);
$final_arr = $arr;
$tmp_array = array();
$actions = array();
for ($i=0; $i < sizeof($arr); $i++) {
$num = $i+1;
$tmp = array();
for ($o=0; $o < sizeof($arr); $o++) {
if($arr[$o]['pos'] == 0)continue;
if($arr[$o]['pos'] == $num){
array_push($tmp,$arr[$o]);
}
}
if($tmp){
usort($tmp,function($a,$b){
return $a['date'] > $b['date'];
});
for ($o=0; $o < sizeof($tmp); $o++) {
array_push($tmp_array,$tmp[$o]);
}
}
}
for ($i=0; $i < sizeof($tmp_array); $i++) {
for ($o=0; $o < sizeof($arr); $o++) {
if($final_arr[$o]['id'] == $tmp_array[$i]['id']){
array_splice($final_arr, $tmp_array[$i]['pos']-1, 0, array_splice($final_arr, $o, 1));
}
}
}
$output = json_encode($final_arr,JSON_PRETTY_PRINT);
printf($output);
Result:
[
{
"id": "1",
"pos": "1",
"date": "0"
},
{
"id": "6",
"pos": "2",
"date": "0"
},
{
"id": "4",
"pos": "3",
"date": "0"
},
{
"id": "5",
"pos": "4",
"date": "1"
},
{
"id": "2",
"pos": "5",
"date": "0"
},
{
"id": "3",
"pos": "4",
"date": "0"
}
]

SSRS - Sort by Colors

I am trying to sort a column in SSRS by the Font Color of that column, but am unable to grasp how... The color code that I have developed works as such.
=Switch(Fields!Prk_name.Value = "Lot 1", "DarkGoldenrod",
Fields!Emp_default.Value = "L" OR Fields!Emp_default.Value = "B", "Black",
Fields!Emp_default.Value = "C" AND Fields!Perm_prk.Value = "Y", "Green",
Fields!Emp_default.Value = "C", "Purple")
What I was think of running under the SortExpression is this:
=Switch(Fields!Name.Color = "DarkGoldenrod" SortExpression (),
Fields!Name.Color = "Black" SortExpression (),
So on and so forth just don't know what to put for SortExpression? I would need a way to sort for all 4 color types the base form of this is group by color then sort ABC.
Chris Lätta's post gave me an idea I gave that a try still does not work, but it might help to narrow down what I am looking for.
=Switch(Fields!Name.Color = "Darkgoldenrod", 1,
Fields!Name.Color = "Purple", 2,
Fields!Name.Color = "Black", 3,
Fields!Name.Color = "Green", 4,
True, 5)
Just sort by a number as your first sort expression:
=Switch(Fields!Prk_name.Value = "Lot 1", 1,
Fields!Emp_default.Value = "L" OR Fields!Emp_default.Value = "B", 2,
Fields!Emp_default.Value = "C" AND Fields!Perm_prk.Value = "Y", 3,
Fields!Emp_default.Value = "C", 4,
True, 5)
then add another sort criteria to sort by the ABC column.

ruby - get all values for particular key from JSON string

this is pretty straight forward im sure, but im feeling braindead right now, and can't figure this out....
I have this JSON response, and just want to grab all the values for the key "price", and dump them all into an array, so i can get the average for both of them.
{
"status": "success",
"data": {
"network": "DOGE",
"prices": [
{
"price": "0.00028055",
"price_base": "USD",
"exchange": "bter",
"time": 1407184167
},
{
"price": "0.00022007",
"price_base": "USD",
"exchange": "cryptsy",
"time": 1407184159
}
]
}
}
this is my code thus far:
data = ActiveSupport::JSON.decode(response)
status = data["status"]
if status == "success"
total = ......what do i need to do here?...
end
thanks in advance
:)
How to sum array of numbers in Ruby?
Except you yield a hash, not a number. So you drill in.
And since the values are strings, you have to convert them to floats to do math.
total = data["data"]["prices"].reduce(0.0) do |sum, hash|
sum + hash["price"].to_f
end
Out of curiosity, how were you stuck? What was the logical gap in your understanding that prevented you from finding a solution?

Keep id order as in query

I'm using elasticsearch to get a mapping of ids to some values, but it is crucial that I keep the order of the results in the order that the ids have.
Example:
def term_mapping(ids)
ids = ids.split(',')
self.search do |s|
s.filter :terms, id: ids
end
end
res = term_mapping("4,2,3,1")
The result collection should contain the objects with the ids in order 4,2,3,1...
Do you have any idea how I can achieve this?
If you need to use search you can sort ids before you send them to elasticsearch and retrive results sorted by id, or you can create a custom sort script that will return the position of the current document in the array of ids. However, a simpler and faster solution would be to simply use Multi-Get instead of search.
One option is to use the Multi GET API. If this doesn't work for you, another solution is to sort the results after you retrieve them from es. In python, this can be done this way:
doc_ids = ["123", "333", "456"] # We want to keep this order
order = {v: i for i, v in enumerate(doc_ids)}
es_results = [{"_id": "333"}, {"_id": "456"}, {"_id": "123"}]
results = sorted(es_results, key=lambda x: order[x['_id']])
# Results:
# [{'_id': '123'}, {'_id': '333'}, {'_id': '456'}]
May be this problem is resolved,, but someone will help with this answer
we can used the pinned_query for the ES. Do not need the loop for the sort the order
**qs = {
"size" => drug_ids.count,
"query" => {
"pinned" => {
"ids" => drug_ids,
"organic" => {
"terms": {
"id": drug_ids
}
}
}
}
}**
It will keep the sequence of the input as it

How do you count the words in an array of strings with LINQ?

Given an array like {"one two", "three four five"}, how'd you calculate the total number of words contained in it using LINQ?
You can do it with SelectMany:
var stringArray = new[] {"one two", "three four five"};
var numWords = stringArray.SelectMany(segment => segment.Split(' ')).Count();
SelectMany flattens the resulting sequences into one sequence, and then it projects a whitespace split for each item of the string array...
I think Sum is more readable:
var list = new string[] { "1", "2", "3 4 5" };
var count = list.Sum(words => words.Split().Length);
Or if you want to use the C# language extensions:
var words = (from line in new[] { "one two", "three four five" }
from word in line.Split(' ', StringSplitOptions.RemoveEmptyEntries)
select word).Count();
Not an answer to the question (that was to use LINQ to get the combined word count in the array), but to add related information, you can use strings.split and strings.join to do the same:
C#:
string[] StringArray = { "one two", "three four five" };
int NumWords = Strings.Split(Strings.Join(StringArray)).Length;
Vb.Net:
Dim StringArray() As String = {"one two", "three four five"}
Dim NumWords As Integer = Split(Join(StringArray)).Length

Resources