sorting lua tables with a table of boolean values - sorting

I've searched high and low and have attempted to accomplish this in different stages.
I'm trying to sort a couple of tables that based on another table values. I've tried to sort these tables by seeding a k, v where v is a boolean.
Here's what I've got so far.. And thank you in advance for any help.
function byInstallsField(x,y)
-- cant seem to make sens out of the sorting
if x.installed then return true
elseif y.installed == false then return false
end
end
-- var is the index passed into the function
-- pRect:new is a custom lib for rect' drawing
playerRect[ var ] = pRect:new(_W + dimesion_for_rect * var, 0,
dimesion_for_rect,
dimesion_for_rect,
3 ) -- _x, _y , _hieght, _width, round
playerRect.installed = inst;
table.sort( playerRect, byInstallsField )
downloadedImage[ var ] = fb_friends:new(var, imageOnFile,
playerRect[ var ].x,
playerRect[ var ].y,
0.25, 0.25, 0, dimesion_for_rect - 5)
downloadedImage[ var ].id = var
downloadedImage.installed = inst
table.sort( downloadedImage, byInstallsField )
The outcome that I wish would to have the playerRect & the downloadedImage tables to sorted so that the installed that = true would lead the arrays..
player 1.installed = true , player 2.installed = true , player 3.installed = false

The comparison function given to table.sort must satisfy the strict ordering relation. In particular, given a and b if byInstall(a, b) is true then byInstall(b, a) must return false.
Here's a simple example:
local player = {
{"alice", installed = false},
{"bob", installed = true},
{"carol", installed = true},
{"dave", installed = true},
{"matthew", installed = false},
{"steve", installed = true},
}
function byInstall(first, second)
return first.installed and not second.installed
end
table.sort(player, byInstall)
After the sort, subtables with installed = true will be grouped together. The table player will look like:
{
{
"steve",
installed = true
},
{
"dave",
installed = true
},
{
"carol",
installed = true
},
{
"bob",
installed = true
},
{
"matthew",
installed = false
},
{
"alice",
installed = false
}
}

Related

Google sheets auto sort script modification to trigger only on specified column change

I have this auto sort script and it works great but I can't figure out how to change two things.
Instead of the script being triggered by every change in the entire sheet I'd like it to trigger when only two specific columns are edited (C and D).
SHEET_NAME = "North Tonawanda";
SORT_DATA_RANGE = "C:D";
SORT_ORDER = [
{column: 3, ascending: true}, // 3 = column number, sorting by descending order
{column: 4, ascending: true} // 1 = column number, sort by ascending order
];
function onEdit(e){
multiSortColumns();
}
function multiSortColumns(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(SHEET_NAME);
var range = sheet.getRange(SORT_DATA_RANGE);
range.sort(SORT_ORDER);
ss.toast('Sort Completed.');
}
Answer
I would rewrite the script as follows. This makes it visually clearer and the onEdit trigger uses the SORT_ORDER variable to see the columns that trigger the function:
Code
SHEET_NAME = "North Tonawanda";
SORT_DATA_RANGE = "C:D";
SORT_ORDER = [
{ column: 3, ascending: true },
{ column: 4, ascending: true }
];
function multiSortColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(SHEET_NAME);
var range = sheet.getRange(SORT_DATA_RANGE);
range.sort(SORT_ORDER);
ss.toast('Sort Completed.');
}
function onEdit(e) {
var editedSheet = e.range.getSheet().getName()
var columnStart = e.range.columnStart
var columnEnd = e.range.columnEnd
if (SHEET_NAME == editedSheet
&& columnStart >= SORT_ORDER[0]["column"]
&& columnEnd <= SORT_ORDER[1]["column"]) {
multiSortColumns()
}
}
References:
Simple Triggers
Event Objects
I believe your goal as follows.
From your question and your script, you want to run the function of multiSortColumns() when the columns "C" and "D" of the sheet North Tonawanda are edited.
In this case, I would like to propose to achieve your goal using the event object. When your script is modified, it becomes as follows.
Modified script:
From:
function onEdit(e){
multiSortColumns();
}
To:
function onEdit(e){
const range = e.range;
if (range.getSheet().getSheetName() != SHEET_NAME || (range.columnStart != 3 && range.columnStart != 4)) return;
multiSortColumns();
}
References:
Simple Triggers
Event Objects

How to merge two rethinkdb documents using some function

I want to translate a merge function from the following JS code to us in RQL:
var d1 = {
del: {
1: {n: 1, v: 100, vFx:[100, 110]},
2: {n: 1, v: 100, vFx:[100, 110]}
}};
var d2 = {
del: {
2: {n: 1, v: 100, vFx:[100, 110]},
3: {n: 1, v: 100, vFx:[100, 110]}
}};
function merge(d1, d2) {
for(k in d2.del){
v = d2.del[k];
d1v = d1.del[k];
if(!d1v){
d1.del[k] = v;
} else{
d1v.n += v.n;
d1v.v += v.v;
for(var i = 0, _len = v.vFx.length; i < _len; i++)
d1v.vFx[i] += v.vFx[i];
}
}
};
// test
merge(d1, d2);
console.log(d1);
// GOAL
r.do(d1, d2, merge) // this of course doesn't work
My main problem is how to iterate through keys of a document? r.forEach requires me to make a save inside. My use case is that I want to use this merge function in update:
rqlexpr.update(merge(d1, r.row))
You can map over the keys of a document with keys, and construct an object with object. For example:
d1.merge(
r.object(
d2('del').keys().concatMap(function(key) {
return r.branch(
d1('del').hasField(key).not(),
[key, d2('del').getField(key)],
[key, d1('del').getField(key) + d2('del').getField(key)]
)
})
)
)

How to programmatically enumerate an enum type?

Say I have a TypeScript enum, MyEnum, as follows:
enum MyEnum {
First,
Second,
Third
}
What would be the best way in TypeScript 0.9.5 to produce an array of the enum values? Example:
var choices: MyEnum[]; // or Array<MyEnum>
choices = MyEnum.GetValues(); // plans for this?
choices = EnumEx.GetValues(MyEnum); // or, how to roll my own?
This is the JavaScript output of that enum:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["First"] = 0] = "First";
MyEnum[MyEnum["Second"] = 1] = "Second";
MyEnum[MyEnum["Third"] = 2] = "Third";
})(MyEnum || (MyEnum = {}));
Which is an object like this:
{
"0": "First",
"1": "Second",
"2": "Third",
"First": 0,
"Second": 1,
"Third": 2
}
Enum Members with String Values
TypeScript 2.4 added the ability for enums to possibly have string enum member values. So it's possible to end up with an enum that look like the following:
enum MyEnum {
First = "First",
Second = 2,
Other = "Second"
}
// compiles to
var MyEnum;
(function (MyEnum) {
MyEnum["First"] = "First";
MyEnum[MyEnum["Second"] = 2] = "Second";
MyEnum["Other"] = "Second";
})(MyEnum || (MyEnum = {}));
Getting Member Names
We can look at the example immediately above to try to figure out how to get the enum members:
{
"2": "Second",
"First": "First",
"Second": 2,
"Other": "Second"
}
Here's what I came up with:
const e = MyEnum as any;
const names = Object.keys(e).filter(k =>
typeof e[k] === "number"
|| e[k] === k
|| e[e[k]]?.toString() !== k
);
Member Values
Once, we have the names, we can loop over them to get the corresponding value by doing:
const values = names.map(k => MyEnum[k]);
Extension Class
I think the best way to do this is to create your own functions (ex. EnumEx.getNames(MyEnum)). You can't add a function to an enum.
class EnumEx {
private constructor() {
}
static getNamesAndValues(e: any) {
return EnumEx.getNames(e).map(n => ({ name: n, value: e[n] as string | number }));
}
static getNames(e: any) {
return Object.keys(e).filter(k =>
typeof e[k] === "number"
|| e[k] === k
|| e[e[k]]?.toString() !== k
);
}
static getValues(e: any) {
return EnumEx.getNames(e).map(n => e[n] as string | number);
}
}
With TypeScript >= 2.4 you can define string enums:
enum Color {
RED = 'Red',
ORANGE = 'Orange',
YELLOW = 'Yellow',
GREEN = 'Green',
BLUE = 'Blue',
INDIGO = 'Indigo',
VIOLET = 'Violet'
}
JavaScript ES5 output:
var Color;
(function (Color) {
Color["RED"] = "Red";
Color["ORANGE"] = "Orange";
Color["YELLOW"] = "Yellow";
Color["GREEN"] = "Green";
Color["BLUE"] = "Blue";
Color["INDIGO"] = "Indigo";
Color["VIOLET"] = "Violet";
})(Color || (Color = {}));
Which is an object like this:
const Color = {
"RED": "Red",
"ORANGE": "Orange",
"YELLOW": "Yellow",
"GREEN": "Green",
"BLUE": "Blue",
"INDIGO": "Indigo",
"VIOLET": "Violet"
}
Thus, in the case of string enums, no need to filter things,
Object.keys(Color) and Object.values(Color) are enough:
const colorKeys = Object.keys(Color) as (keyof typeof Color)[];
console.log('colorKeys =', colorKeys);
// ["RED", "ORANGE", "YELLOW", "GREEN", "BLUE", "INDIGO", "VIOLET"]
const colorValues = Object.values(Color);
console.log('colorValues =', colorValues);
// ["Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"]
colorKeys.map(colorKey => {
console.log(`color key = ${colorKey}, value = ${Color[colorKey]}`);
});
/*
color key = RED, value = Red
color key = ORANGE, value = Orange
color key = YELLOW, value = Yellow
color key = GREEN, value = Green
color key = BLUE, value = Blue
color key = INDIGO, value = Indigo
color key = VIOLET, value = Violet
*/
See online example on TypeScript playground
There is no concept of RTTI (runtime type information) in TypeScript (think: reflection) so in order to do this, knowledge of the transpiled JavaScript is required. So, assuming TypeScript 0.95:
enum MyEnum {
First, Second, Third
}
becomes:
var MyEnum;
(function(MyEnum) {
MyEnum[MyEnum["First"] = 0] = "First";
MyEnum[MyEnum["Second"] = 1] = "Second";
MyEnum[MyEnum["Third"] = 2] = "Third";
}
So, this is modeled as a regular object in javascript, where MyEnum.0 == "First" and MyEnum.First == 0. So, to enumerate all of the enum names, you need to get all properties that belong to the object and that are also not numbers:
for (var prop in MyEnum) {
if (MyEnum.hasOwnProperty(prop) &&
(isNaN(parseInt(prop)))) {
console.log("name: " + prop);
}
}
Ok, so now I've told you how to do it, I'm allowed to tell you this is a bad idea. You're not writing a managed language, so you can't bring these habits. It's still just plain old JavaScript. If I wanted to use a structure in JavaScript to populate some kind of choices list, I would use a plain old array. An enum is not the right choice here, pun intended. The goal of TypeScript is to generate idiomatic, pretty JavaScript. Using enums in this way does not preserve this goal.
You can add functions to get the names and indices of the enum:
enum MyEnum {
First,
Second,
Third
}
namespace MyEnum {
function isIndex(key):boolean {
const n = ~~Number(key);
return String(n) === key && n >= 0;
}
const _names:string[] = Object
.keys(MyEnum)
.filter(key => !isIndex(key));
const _indices:number[] = Object
.keys(MyEnum)
.filter(key => isIndex(key))
.map(index => Number(index));
export function names():string[] {
return _names;
}
export function indices():number[] {
return _indices;
}
}
console.log("MyEnum names:", MyEnum.names());
// Prints: MyEnum names: ["First", "Second", "Third"]
console.log("MyEnum indices:", MyEnum.indices());
// Prints: MyEnum indices: [0, 1, 2]
Note that you could just export the _names and _indices consts rather than exposing them through an exported function, but because the exported members are members of the enum it is arguably clearer to have them as functions so they are not confused with the actual enum members.
It would be nice if TypeScript generated something like this automatically for all enums.
I used the solution proposed by David Sherret and wrote an npm library you can use named enum-values...
Git: enum-values
// Suppose we have an enum
enum SomeEnum {
VALUE1,
VALUE2,
VALUE3
}
// names will be equal to: ['VALUE1', 'VALUE2', 'VALUE3']
var names = EnumValues.getNames(SomeEnum);
// values will be equal to: [0, 1, 2]
var values = EnumValues.getValues(SomeEnum);
A one-liner to get a list of entries (key-value objects/pairs):
Object.keys(MyEnum).filter(a=>a.match(/^\D/)).map(name=>({name, value: MyEnum[name] as number}));
enum MyEnum {
First, Second, Third, NUM_OF_ENUMS
}
for(int i = 0; i < MyEnum.NUM_OF_ENUMS; ++i) {
// do whatever you need to do.
}
If you want to associate strings values to your enum these methods don't works. To have a generic function you can do :
function listEnum(enumClass) {
var values = [];
for (var key in enumClass) {
values.push(enum[key]);
}
values.length = values.length / 2;
return values;
}
It's works because TypeScript will add keys in first step, and values in second step.
In TypeScript it's:
var listEnums = <T> (enumClass: any): T[]=> {
var values: T[] = [];
for (var key in enumClass) {
values.push(enumClass[key]);
}
values.length = values.length / 2;
return values;
};
var myEnum: TYPE[] = listEnums<TYPE>(TYPE);
joe's answer just made me realize that is much more easier to rely on the first N numeric keys than making more complex testings:
function getEnumMembers(myEnum): string[]
{
let members = []
for(let i:number = 0; true; i++) {
if(myEnum[i] === undefined) break
members.push(myEnum[i])
}
return members
}
enum Colors {
Red, Green, Blue
}
console.log(getEnumMembers(myEnum))
Iterating over an enum
String Enums are best used for this. Here is an example:
// This is a string enum
enum MyEnum {
First = 'First',
Second = 'Second',
Third = 'Third',
}
// An enum is a TS concept
// However his MyEnum compiles to JS object:
// {
// "First": "First",
// "Second": "Second",
// "Third": "Third"
// }
// Therefore we can get the keys in the following manner:
const keysArray = Object.keys(MyEnum);
for (const key of keysArray) {
console.log(key)
}
// [LOG]: "First"
// [LOG]: "Second"
// [LOG]: "Third"
A type-safe solution could be as follows:
enum Color {
Blue = 'blue',
Green = 'green'
}
enum MoreColor {
Yellow,
Red
}
function getEnumValues<T, K extends keyof T>(enumType: T): Array<T[K]> {
return getEnumKeys<T, K>(enumType).map((x) => enumType[x]);
}
function getEnumKeys<T, K extends keyof T>(enumType: T): Array<K> {
return Object.keys(enumType)
.filter((x) => Number.isNaN(Number(x)))
.map((x) => x as K);
}
// return type is Color[]
const colorValues = getEnumValues(Color); // ["blue", "green"]
// return type is MoreColor[]
const moreColorValues = getEnumValues(MoreColor); // [0, 1]
// return type is Array<"Blue" | "Green">
const colorKeys = getEnumKeys(Color); // ["Blue", "Green"]
// return type is Array<"Yellow" | "Red">
const moreColorKeys = getEnumKeys(MoreColor); // ["Yellow", "Red"]
But keep in mind that this solution does not force you to pass just enums to the function.
for nodejs:
const { isNumber } = require('util');
Object.values(EnumObject)
.filter(val => isNumber(val))
.map(val => {
// do your stuff
})

get sum from list of objects in linq C#

I have list of objects as described below:
List<Maths> mObjs = new List<Maths>();
mObjs.Add(new Maths{ Name = "Jack", M1 = 10, M2 = 5, M3 = 0, M4 = 2, M5 =1 });
mObjs.Add(new Maths { Name = "Jill", M1 = 2, M2 = 3, M3 = 4, M4 = 1, M5 = 0 });
mObjs.Add(new Maths { Name = "Michel", M1 = 12, M2 = 15, M3 = 10, M4 = 12, M5 = 11 });
Now I need to calculated the total aggregated value for all three people.
I need to get the below results, probably a new other class
List<Results> mRes = new List<Results>();
public class Results{
public string Name { get; set; }
public int TotalValue { get; set; }
}
mRes.Name = "M1"
mRes.TotalValue = 24;
mRes.Name = "M2"
mRes.TotalValue = 23;
mRes.Name = "M3"
mRes.TotalValue = 14;
mRes.Name = "M4"
mRes.TotalValue = 15;
mRes.Name = "M5"
mRes.TotalValue = 12;
How can I get this data from mObjs using linq query? I know we can do it using for, but want to know if there are any better ways to get this using linq query because that reduces lines of code and I have similar requirements in many other places and dont want to write number of foreach or fors every time.
You can use a pre selection list to list both the name and the field to select
var lookups = new Dictionary<string,Func<Maths,int>> {
{"M1", x => x.M1 },
{"M2", x => x.M2 },
{"M3", x => x.M3 },
{"M4", x => x.M4 },
{"M5", x => x.M5 },
};
Then you can simply do
var mRes = dlookups.Select(x => new Results {
Name= x.Key,
TotalValue = mObjs.Sum(x.Value)
}).ToList();
BEGIN UPDATED*
In response to comments
The lambda expression is just a function from your source class to an int.
For example
class Sub1 {
string M3 {get;set;}
int M4 {get;set;}
}
class Math2 {
string Name {get;set;}
string M1 {get;set;}
string M2 {get;set;}
Sub1 Sub {get;set;}
}
var lookups = new Dictionary<string,Func<Math2,int>> {
{ "M1", x => int.Parse(x.M1) },
{ "M2", x => int.Parse(x.M2) },
{ "M3", x => int.Parse(x.Sub.M3) },
{ "M4", x => int.Parse(x.Sub.M4} }
};
Or if you want to put a little error checking in, you can either use functions or embed the code.
int GetInt(string source) {
if (source == null) return 0;
int result;
return int.TryParse(source, out result) ? result : 0;
}
var lookups = new Dictionary<string,Func<Math2,int>> {
{ "M1", x => {
int result;
return x == null ? 0 : (int.TryParse(x,out result) ? result : 0);
},
{ "M2", x => GetInt(x) },
{ "M3", x => x.Sub == null ? 0 : GetInt(x.Sub.M3) },
{ "M4", x => x.Sub == null ? 0 : x.Sub.M4}
};
END UPDATED
If you want to go further you could use reflection to build the lookups dictionary.
Here is a helper function that will generate the lookups for all Integer properties of a class.
public Dictionary<string,Func<T,int>> GenerateLookups<T>() where T: class {
// This just looks for int properties, you could add your own filter
var properties = typeof(T).GetProperties().Where(pi => pi.PropertyType == typeof(int));
var parameter = Expression.Parameter(typeof(T));
return properties.Select(x => new {
Key = x.Name,
Value = Expression.Lambda<Func<T,int>>(Expression.Property(parameter,x),parameter).Compile()
}).ToDictionary (x => x.Key, x => x.Value);
}
Now you can just do:
var mRes=GenerateLookups<Maths>().Select( x => new Results
{
Name = x.Key,
TotalValue = mObjs.Sum(x.Value)
}).ToList();
Not very smart but efficient and readable:
int m1Total= 0;
int m2Total= 0;
int m3Total= 0;
int m4Total= 0;
int m5Total= 0;
foreach(Maths m in mObjs)
{
m1Total += m.M1;
m2Total += m.M2;
m3Total += m.M3;
m4Total += m.M4;
m5Total += m.M5;
}
List<Results> mRes = new List<Results>
{
new Results{ Name = "M1", TotalValue = m1Total },
new Results{ Name = "M2", TotalValue = m2Total },
new Results{ Name = "M3", TotalValue = m3Total },
new Results{ Name = "M4", TotalValue = m4Total },
new Results{ Name = "M5", TotalValue = m5Total },
};
Result:
Name: "M1" TotalValue: 24
Name: "M2" TotalValue: 23
Name: "M3" TotalValue: 14
Name: "M4" TotalValue: 15
Name: "M5" TotalValue: 12
Edit: since you've explicitly asked for LINQ, if the properties are always these five i don't see why you need to use LINQ at all. If the number can change i would use a different structure.
You could for example use
a single List<Measurement> instead of multiple properties where Measurement is another class that stores the name and the value or you could use
a Dictionary<string, int> for efficient lookup.
You can try out some thing like this :
mRes.Add(new Results() { Name = "M1", TotalValue = mObjs.Sum(x => x.M1) });
To programmatically iterate through all the class properties, you might need to employ reflection.

reduce number of LINQ queries

void Main()
{
List<SomeContainer> someList = new List<SomeContainer>();
someList.Add(new SomeContainer { a = true, b = true, c = true });
someList.Add(new SomeContainer { a = false, b = true, c = false });
someList.Add(new SomeContainer { a = true, b = true, c = false });
someList.Add(new SomeContainer { a = true, b = false, c = false });
someList.Add(new SomeContainer { a = true, b = false, c = false });
someList.Add(new SomeContainer { a = true, b = true, c = false });
someList.Add(new SomeContainer { a = true, b = true, c = false });
var q1 = from container in someList where container.a == true select container.a;
var q2 = from container in someList where container.b == true select container.b;
var q3 = from container in someList where container.c == true select container.c;
q1.Count().Dump();
q2.Count().Dump();
q3.Count().Dump();
}
class SomeContainer
{
public Boolean a { get; set; }
public Boolean b { get; set; }
public Boolean c { get; set; }
}
is it possible to generate something like this with one querry:a | b | c6 | 5 | 1
Not sure whether you will treat this as optimization, but this will iterate over your list only once:
var result = someList
.Select(i => new [] {i.a? 1:0, i.b? 1:0, i.c? 1:0,})
.Aggregate((i, acc) => new [] {i[0]+acc[0], i[1]+acc[1], i[2]+acc[2]});
int countA = result[0];
int countB = result[1];
int countC = result[2];
int a = 0, b = 0, c = 0;
var qAll = (from ct in someList
select new{ ac = ct.a ? a++ : 0,
bc = ct.b ? b++ : 0,
cc = ct.c ? c++ : 0}).ToList();
//Now a, b, c variables should have the count of a==true, b==true & c==true in somelist.
//Console.WriteLine("A= {0}, B={1}, C={2}", a, b, c);
The Aggregate extension methods allow you combine values from enumerables in arbitrary ways. You can aggregate a tuple of three integers representing a count, and provide a function that will increment the three counters on the tuple depending on the input.
It suspect it may could look contrived for this example, and it may be slower than a regular for loop.
Sometimes Aggregate shines though. I used it to compute the bounding rectangle of a list of rectangles: var union = rects.Aggregate(Rectangle.Union);
someList.Count(container => container.a).Dump();
someList.Count(container => container.b).Dump();
someList.Count(container => container.c).Dump();
//even when looking for false values it looks nice...
someList.Where(container => container.a == false).Count(container => container.a).Dump();

Resources