LINQ query to order elements between two variables - json

a complete beginner here.
I am trying to create a JSONResult which I am trying to get to return between two variables.
Here is the action:
public JsonResult GetVoices(int? PageNumber, int? PageSize)
{
var StartRow = ((PageNumber - 1) * PageSize) + 1;
var EndRow = PageNumber * PageSize;
var i = 0;
var data = (from a in db.Content
select new
{
RowNumber = i++,
Id = a.Id,
Title = a.Title,
Description = a.Description,
CreatedAt = a.CreatedAt
}).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
As you can see there are two parameters which eventually specify the Row to start from and end from. I want all the RowNumber returned to be between StartRow and LastRow

You're looking for something like this:
public JsonResult GetVoices(int PageNumber, int PageSize) =>
Json((from a in db.Content.ToArray()
let StartRow = ((PageNumber - 1) * PageSize) + 1
let EndRow = PageNumber * PageSize
from RowNumber in Enumerable.Range(StartRow, EndRow - StartRow + 1)
select new
{
RowNumber = RowNumber,
Id = a.Id,
Title = a.Title,
Description = a.Description,
CreatedAt = a.CreatedAt
}).ToList(), JsonRequestBehavior.AllowGet);

So you have a PageSize and a PageNumber, and you want all rows that are on the page with PageNumber.
Page 0 contains rows 0 to PageSize - 1
Page 1 contains rows PageSize to 2 * PageSize - 1
Page 2 contains rows 2 * PageSize to 3 * PageSize - 1
etc.
This seems to be a very common problem, so let's not limit ourselves to a solution for this problem only, let's make a solution suitable for all sequences that needs to be divided into pages.
My advice would be to create an extension method of IQueryable<T>, so you can intertwine the pagination with other LINQ methods. If you are not familiar with extension methods, consider to read Extension Methods Demystified
Input: a sequence of similar items: IQueryable<T>, a PageSize and a PageNumber.
Output: all rows on page PageNumber, according to the definition above. So each page, except the last one has PageSize number of rows. The last Page will have Total number of rows % PageSize
I decided to return IQueryable<T>, not ICollection<T>. This has the advantage that if you don't enumerate the rows on a page, the data is not fetched. The disadvantages is that you have to calculate the number of rows on each page, and the number of pages. If you think you will always enumerate all rows on all pages, consider to return ICollection<T>.
public IQueryable<T>> FetchPage<T>(
this IQueryable<T> source,
int pageNumber,
int pageSize)
{
// TODO: check input parameters: source not null, pageSize > 0, pageNumber >= 0
return source.Skip(pageNumber * pageSize)
.Take(pageSize);
}
Usage: if you have a table of Products, and you want to divide this into Pages of size 25, and you want to fetch Page 3, with the cheapest Products first:
IQueryable<Product> productsOnPage3 = dbContext.Products
.OrderBy(product => product.Price)
.FetchPage(3, 25)
.ToList();
If you don't want the complete row on your pages, you can add a Select.
Consider to create extension methods with parameters selector like in LINQ Select:
public IQueryable<T>> FetchPage<T>(
this IQueryable<T> source,
int pageNumber,
int pageSize,
Expression<Func<TSource,TResult>> selector)
{
// TODO: check input parameter selector
return source.FetchPage(pageNumber, pageSize)
.Select(selector);
}
And maybe also an overload with a sortKey.

Related

How to use aggregate functions in CodeEffects Rule Editor?

Can anyone Please guide me how can I create an aggregator like SUM(), AVG() in Codeeffects RuleEditor. And these should be passed with set of integer values from the rule editor.
Like if there is an attribute like score which is of int type.........
Rule will be like:
If score equal to Zero then set score to SUM(10,20,30,40)
After this is should get this score as 100
Define a list of integers in your source class:
public List<int> Integers {get;set;}
Define two action methods as well:
public void Sum ( List<int> list )
{
return list.Sum( );
}
public void Add ( int i )
{
this.Integers.Add( i );
}
public int Modulus (int operandOne, int operandTwo)
{
return operandOne % operandTwo;
}
Now give your class as the source to the rule editor and create your rule:
If Modulus( Score, 2 ) is equal to 3
then
Add(10) and Add(20) and Add(30) and Add(40) and
set Score to Sum ( Integers )

Automatically generate a unique sequential ID in Google Sheets

In Google Sheets, I have a spreadsheet called Events/Incidents which staff from various branches populate. I want Column B to automatically generate a unique ID based on the year in column A and the previously populated event. Given that there could be several events on a particular day, rows in column A could have duplicate dates.
The following is an example of what I am looking for in column B:
There can be no duplicates. Would really appreciate some help with either code or formula.
There are my thoughts https://github.com/contributorpw/google-apps-script-snippets/blob/master/snippets/spreadsheet_autoid/autoid.js
The main function gets a sheet and makes the magic
/**
*
* #param {GoogleAppsScript.Spreadsheet.Sheet} sheet
*/
function autoid_(sheet) {
var data = sheet.getDataRange().getValues();
if (data.length < 2) return;
var indexId = data[0].indexOf('ID');
var indexDate = data[0].indexOf('DATE');
if (indexId < 0 || indexDate < 0) return;
var id = data.reduce(
function(p, row) {
var year =
row[indexDate] && row[indexDate].getTime
? row[indexDate].getFullYear() % 100
: '-';
if (!Object.prototype.hasOwnProperty.call(p.indexByGroup, year)) {
p.indexByGroup[year] = [];
}
var match = ('' + row[indexId]).match(/(\d+)-(\d+)/);
var idVal = row[indexId];
if (match && match.length > 1) {
idVal = match[2];
p.indexByGroup[year].push(+idVal);
}
p.ids.push(idVal);
p.years.push(year);
return p;
},
{ indexByGroup: {}, ids: [], years: [] }
);
// Logger.log(JSON.stringify(id, null, ' '));
var newId = data
.map(function(row, i) {
if (row[indexId] !== '') return [row[indexId]];
if (isNumeric(id.years[i])) {
var lastId = Math.max.apply(
null,
id.indexByGroup[id.years[i]].filter(function(e) {
return isNumeric(e);
})
);
lastId = lastId === -Infinity ? 1 : lastId + 1;
id.indexByGroup[id.years[i]].push(lastId);
return [
Utilities.formatString(
'%s-%s',
id.years[i],
('000000000' + lastId).slice(-3)
)
];
}
return [''];
})
.slice(1);
sheet.getRange(2, indexId + 1, newId.length).setValues(newId);
}
I think it can be simplified in the feature.
There is an easier way to generate unique values that works for me, pick a #, then do +1. Ctrl C, then Ctrl shift V to paste back and remove the formula. Now you are left with thousands of unique IDs.
This is a manual solution but you can do an entire database in a matter of seconds every once in a while.

Parsing variable length record to table columns where specific column is dynamic in SSIS 2016

I have a table that has 45 columns for tax values
| Tax1 | Tax2 | .......... | Tax 44 | Tax45 |
I read in a variable length positional record that can contain zero to 90 values. The record is structured so that the first 3 characters are the tax code (values 001 - 045) and the next 7 characters are the tax value:
Examples:
0010013.990140005.00
0040002.00
0150001.150320002.200410014.250420012.990430000.500440001.750450004.68
What I would like to do is, for each record:
if ISNULL(record) or LEN(record) < 10 (3 characters for the code, 7 characters for the value)
quit
else
determine the amount of 10 character sections
for each 10 character section
taxCode = SUBSTRING(record, 1, 3)
taxValue = SUBSTRING(record, 4, 10)
table.Tax(taxCode).Value = taxValue (ex: using the first example record, column Tax1 will hold a value of 0013.99, Tax14 will be 0005.00)
next section
all other Tax[n] columns will have a value of 0.00
end if
Is there a way to do this without having to create 45 variables, one for each corresponding column?
EDIT:
I apologize for the lack of clarity. I receive a flat file from our VMS database. This file has multiple record types per file (ie: IT01, IT02, IT03, IT04, IT05, IT06, IT07). Each record type is on its own line. I read this file into a staging table, which the record type from the data on the line. For example (this is the record type I am referring to in my question):
IT06404034001005.000031013.000
This gets loaded into my staging table as:
RecordType | RecordData |
------------------------------------------
IT06 | 404034001005.000031013.000
The RecordData field is then able to be broken down further as:
ItemNumber | RecordData |
-------------------------------------
404034 | 001005.000031013.000
With a little bit of up-front work, I was able to create a script task to do exactly as I needed it to.
Step 1: add a script component. set it up as a transformation
Step 2: define all of the output columns necessary (long and tedious task, but it worked)
Step 3: put the following code in the script
public override void Input0_ProcessInputRow(Input0Buffer Row){
int sizeOfDataSegment = 11; // size of single record to be parsed (item number/next price)
string recordDetail = Row.RecordDetail.ToString().Trim();
string itemNumber = recordDetail.Substring(0, 6);
//System.Windows.Forms.MessageBox.Show(String.Format("Record Detail: {0}", recordDetail));
// we need a record for every item number, regardless if there are taxes or not
Row.Company = Variables.strCompanyName;
Row.ItemNumber = itemNumber;
if (recordDetail.Length > 6){
string taxData = recordDetail.Substring(6);
if (string.IsNullOrEmpty(taxData)){
}
else{
if (taxData.Length % sizeOfDataSegment == 0){
int numberOfTaxes = taxData.Length / sizeOfDataSegment;
//System.Windows.Forms.MessageBox.Show(String.Format("Number of taxe codes: {0}", numberOfTaxes.ToString()));
int posTaxCode = 0;
for (int x = 0; x < numberOfTaxes; x++){
string taxCode = taxData.Substring(posTaxCode, 3);
string taxValue = taxData.Substring(posTaxCode + 3, 8);
string outputColumnName = "TaxOut" + Convert.ToInt32(taxCode).ToString();
//System.Windows.Forms.MessageBox.Show(String.Format("TaxCode: {0}" + Environment.NewLine + "TaxValue: {1}", taxCode, taxValue));
//using taxCode value (ie: 001), find and set the value for the corresponding table column (ie: Tax1)
//foreach (System.Reflection.PropertyInfo dataColumn in Row.GetType().GetProperties()){
foreach (System.Reflection.PropertyInfo dataColumn in Row.GetType().GetProperties()){
if (dataColumn.Name == outputColumnName){
if (Convert.ToDecimal(taxValue) < 0){
// taxValue is a negative number, and therefore a percentage value
taxValue = (Convert.ToDecimal(taxValue) * -1).ToString() + "%";
}
else{
// taxValue is a positive number, and therefore a dollar value
taxValue = "$" + Convert.ToDecimal(taxValue).ToString();
}
dataColumn.SetValue(Row, taxValue);
}
}
posTaxCode += sizeOfDataSegment;
}
}
else{
System.Windows.Forms.MessageBox.Show(String.Format("Invalid record length({0}): {1}", taxData.Length, taxData));
}
}
}
}

Arduino - waiting on function causes a number pile-up

I have a function filledFunction() that returns a float filled:
float filledFunction(){
if (FreqMeasure.available()) {
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 30) {
frequency = FreqMeasure.countToFrequency(sum / count);
a = frequency * x;
b = exp (a);
c = w * b;
d = frequency * z;
e = exp (d);
f = y * e;
float filled = c + f;
sum = 0;
count = 0;
return filled;
}
}
}
When I call this function with
while (1){
fillLevel = filledFunction();
int tofill = 500 - fillLevel;
Serial.print("fillLevel: ");
Serial.println(fillLevel);
Serial.print("tofill: ");
Serial.println(tofill);
The serial monitor should output two numbers that add up to 500 named fillLevel and tofill. Instead I get a repeating sequence of similar values:
http://i.imgur.com/Y9Wu8P2.png
The First two values are correct (410.93 + 89 = 500), but the following 60ish values are unknown to me, and do not belong there.
I am using an arduino nano
The filledFunction() function only returns a value if FreqMeasure.available() returns true AND count > 30. As stated in the answers to this question the C89, C99 and C11 standards all say that the default return value of a function is undefined (that is if the function completes without executing a return statement). Which really means that anything could happen, such as outputting arbitrary numbers.
In addition, the output that you're seeing starts off 'correct' with one of the numbers subtracted from 500, even when they have weird values such as 11699.00 and -11199 (which equals 500 - 11699.00). However, lower down in the output this seems to break down and the reason is that on Arduino Nano an int can only hold numbers up to 32767 and therefore the result of the subtraction is too big and 'overflows' to be a large negative number.
Fixing the filledFunction() function to explicitly return a value even if FreqMeasure.available() is false or count <= 30 and ensuring that it can't return a number greater than 500 will likely solve these issues.

Finding closest match in collection of numbers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 8 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
So I got asked today what was the best way to find the closes match within a collection.
For example, you've got an array like this:
1, 3, 8, 10, 13, ...
What number is closest to 4?
Collection is numerical, unordered and can be anything. Same with the number to match.
Lets see what we can come up with, from the various languages of choice.
11 bytes in J:
C=:0{]/:|#-
Examples:
>> a =: 1 3 8 10 13
>> 4 C a
3
>> 11 C a
10
>> 12 C a
13
my breakdown for the layman:
0{ First element of
] the right argument
/: sorted by
| absolute value
# of
- subtraction
Shorter Python: 41 chars
f=lambda a,l:min(l,key=lambda x:abs(x-a))
My attempt in python:
def closest(target, collection) :
return min((abs(target - i), i) for i in collection)[1]
Groovy 28B
f={a,n->a.min{(it-n).abs()}}
Some C# Linq ones... too many ways to do this!
decimal[] nums = { 1, 3, 8, 12 };
decimal target = 4;
var close1 = (from n in nums orderby Math.Abs(n-target) select n).First();
var close2 = nums.OrderBy(n => Math.Abs(n - target)).First();
Console.WriteLine("{0} and {1}", close1, close2);
Even more ways if you use a list instead, since plain ol arrays have no .Sort()
Assuming that the values start in a table called T with a column called N, and we are looking for the value 4 then in Oracle SQL it takes 59 characters:
select*from(select*from t order by abs(n-4))where rownum=1
I've used select * to reduce the whitespace requirements.
Because I actually needed to do this, here is my PHP
$match = 33;
$set = array(1,2,3,5,8,13,21,34,55,89,144,233,377,610);
foreach ($set as $fib)
{
$diff[$fib] = (int) abs($match - $fib);
}
$fibs = array_flip($diff);
$closest = $fibs[min($diff)];
echo $closest;
PostgreSQL:
select n from tbl order by abs(4 - n) limit 1
In the case where two records share the same value for "abs(4 - id)" the output would be in-determinant and perhaps not a constant. To fix that I suggest something like the untested guess:
select n from tbl order by abs(4 - n) + 0.5 * 4 > n limit 1;
This solution provides performance on the order of O(N log N), where O(log N) is possible for example: https://stackoverflow.com/a/8900318/1153319
Ruby like Python has a min method for Enumerable so you don't need to do a sort.
def c(value, t_array)
t_array.min{|a,b| (value-a).abs <=> (value-b).abs }
end
ar = [1, 3, 8, 10, 13]
t = 4
c(t, ar) = 3
Language: C, Char count: 79
c(int v,int*a,int A){int n=*a;for(;--A;++a)n=abs(v-*a)<abs(v-n)?*a:n;return n;}
Signature:
int closest(int value, int *array, int array_size);
Usage:
main()
{
int a[5] = {1, 3, 8, 10, 13};
printf("%d\n", c(4, a, 5));
}
Scala (62 chars), based on the idea of the J and Ruby solutions:
def c(l:List[Int],n:Int)=l.sort((a,b)=>(a-n).abs<(b-n).abs)(0)
Usage:
println(c(List(1,3,8,10,13),4))
PostgreSQL:
This was pointed out by RhodiumToad on FreeNode and has performance on the order of O(log N)., much better then the other PostgreSQL answer here.
select * from ((select * from tbl where id <= 4
order by id desc limit 1) union
(select * from tbl where id >= 4
order by id limit 1)) s order by abs(4 - id) limit 1;
Both of the conditionals should be "or equal to" for much better handling of the id exists case. This also has handling in the case where two records share the same value for "abs(4 - id)" then that other PostgreSQL answer here.
The above code doesn't works for floating numbers.
So here's my revised php code for that.
function find_closest($match, $set=array()) {
foreach ($set as $fib) {
$diff[$fib] = abs($match - $fib);
}
return array_search(min($diff), $diff);
}
$set = array('2.3', '3.4', '3.56', '4.05', '5.5', '5.67');
echo find_closest(3.85, $set); //return 4.05
Python by me and https://stackoverflow.com/users/29253/igorgue based on some of the other answers here. Only 34 characters:
min([(abs(t-x), x) for x in a])[1]
Haskell entry (tested):
import Data.List
near4 = head . sortBy (\n1 n2 -> abs (n1-4) `compare` abs (n2-4))
Sorts the list by putting numbers closer to 4 near the the front. head takes the first element (closest to 4).
Ruby
def c(r,t)
r.sort{|a,b|(a-t).abs<=>(b-t).abs}[0]
end
Not the most efficient method, but pretty short.
returns only one number:
var arr = new int[] { 1, 3, 8, 10, 13 };
int numToMatch = 4;
Console.WriteLine("{0}",
arr.OrderBy(n => Math.Abs(numToMatch - n)).ElementAt(0));
returns only one number:
var arr = new int[] { 1, 3, 8, 10, 13 };
int numToMatch = 4;
Console.WriteLine("{0}",
arr.Select(n => new{n, diff = Math.Abs(numToMatch - n) }).OrderBy(x => x.diff).ElementAt(0).n);
Perl -- 66 chars:
perl -e 'for(qw/1 3 8 10 13/){$d=($_-4)**2; $c=$_ if not $x or $d<$x;$x=$d;}print $c;'
EDITED = in the for loop
int Closest(int val, int[] arr)
{
int index = 0;
for (int i = 0; i < arr.Length; i++)
if (Math.Abs(arr[i] - val) < Math.Abs(arr[index] - val))
index = i;
return arr[index];
}
Here's another Haskell answer:
import Control.Arrow
near4 = snd . minimum . map (abs . subtract 4 &&& id)
Haskell, 60 characters -
f a=head.Data.List.sortBy(compare`Data.Function.on`abs.(a-))
Kdb+, 23B:
C:{x first iasc abs x-}
Usage:
q)a:10?20
q)a
12 8 10 1 9 11 5 6 1 5
q)C[a]4
5
Python, not sure how to format code, and not sure if code will run as is, but it's logic should work, and there maybe builtins that do it anyways...
list = [1,4,10,20]
num = 7
for lower in list:
if lower <= num:
lowest = lower #closest lowest number
for higher in list:
if higher >= num:
highest = higher #closest highest number
if highest - num > num - lowest: # compares the differences
closer_num = highest
else:
closer_num = lowest
In Java Use a Navigable Map
NavigableMap <Integer, Integer>navMap = new ConcurrentSkipListMap<Integer, Integer>();
navMap.put(15000, 3);
navMap.put(8000, 1);
navMap.put(12000, 2);
System.out.println("Entry <= 12500:"+navMap.floorEntry(12500).getKey());
System.out.println("Entry <= 12000:"+navMap.floorEntry(12000).getKey());
System.out.println("Entry > 12000:"+navMap.higherEntry(12000).getKey());
int numberToMatch = 4;
var closestMatches = new List<int>();
closestMatches.Add(arr[0]); // closest tentatively
int closestDifference = Math.Abs(numberToMatch - arr[0]);
for(int i = 1; i < arr.Length; i++)
{
int difference = Math.Abs(numberToMatch - arr[i]);
if (difference < closestDifference)
{
closestMatches.Clear();
closestMatches.Add(arr[i]);
closestDifference = difference;
}
else if (difference == closestDifference)
{
closestMatches.Add(arr[i]);
}
}
Console.WriteLine("Closest Matches");
foreach(int x in closestMatches) Console.WriteLine("{0}", x);
Some of you don't seem to be reading that the list is unordered (although with the example as it is I can understand your confusion). In Java:
public int closest(int needle, int haystack[]) { // yes i've been doing PHP lately
assert haystack != null;
assert haystack.length; > 0;
int ret = haystack[0];
int diff = Math.abs(ret - needle);
for (int i=1; i<haystack.length; i++) {
if (ret != haystack[i]) {
int newdiff = Math.abs(haystack[i] - needle);
if (newdiff < diff) {
ret = haystack[i];
diff = newdiff;
}
}
}
return ret;
}
Not exactly terse but hey its Java.
Common Lisp using iterate library.
(defun closest-match (list n)
(iter (for i in list)
(finding i minimizing (abs (- i n)))
41 characters in F#:
let C x = Seq.min_by (fun n -> abs(n-x))
as in
#light
let l = [1;3;8;10;13]
let C x = Seq.min_by (fun n -> abs(n-x))
printfn "%d" (C 4 l) // 3
printfn "%d" (C 11 l) // 10
printfn "%d" (C 12 l) // 13
Ruby. One pass-through. Handles negative numbers nicely. Perhaps not very short, but certainly pretty.
class Array
def closest int
diff = int-self[0]; best = self[0]
each {|i|
if (int-i).abs < diff.abs
best = i; diff = int-i
end
}
best
end
end
puts [1,3,8,10,13].closest 4