I have two type of value on handlebar page and needs to compare the first one from second.
I can print value of following code
{{articledetails.content_writer_id}}
before writing each loop on page. Now i want to compare the value like following. but i can not get the scope of articledetails.content_writer_id in below code.
{{#each contentwriterdetails}}
{{#compare this.id "==" articledetails.content_writer_id }}
I have already registered compare helper by using this code.
handlebars.registerHelper('compare', function (lvalue, operator, rvalue, options) {
var operators, result;
if (arguments.length < 3) {
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
}
if (options === undefined) {
options = rvalue;
rvalue = operator;
operator = "===";
}
operators = {
'==': function (l, r) { return l == r; },
'===': function (l, r) { return l === r; },
'!=': function (l, r) { return l != r; },
'!==': function (l, r) { return l !== r; },
'<': function (l, r) { return l < r; },
'>': function (l, r) { return l > r; },
'<=': function (l, r) { return l <= r; },
'>=': function (l, r) { return l >= r; },
'typeof': function (l, r) { return typeof l == r; }
};
if (!operators[operator]) {
throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator);
}
result = operators[operator](lvalue, rvalue);
if (result) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
and above helper is working fine as i have checked that.
Any help would be appreciated.
Use the parent's context path:
{{#each contentwriterdetails}}
{{#compare this.id "==" ../articledetails.content_writer_id }}
Related
I'm trying to compare list of music with releaseDate. But I can retrieve music without releaseDate and when I want to sort them, I got an error.
How can I sort / compare nullable datetime and put null releaseDate to the end?
_followedMusic.sort((a, b) {
if (a.releaseDate != null && b.releaseDate != null)
return a.releaseDate.compareTo(b.releaseDate);
else
// return ??
});
Thank you
If you take a look at the documentation for compareTo:
Returns a value like a Comparator when comparing this to other. That is, it returns a negative integer if this is ordered before other, a positive integer if this is ordered after other, and zero if this and other are ordered together.
https://api.dart.dev/stable/2.10.0/dart-core/Comparable/compareTo.html
So your compareTo should just result in returning the values -1, 0 or 1 according to if the compared object should be before, the same position or after the current object.
So in your case if you want your null entries to be at the start of the sorted list, you can do something like this:
void main() {
final list = ['b', null, 'c', 'a', null];
list.sort((s1, s2) {
if (s1 == null && s2 == null) {
return 0;
} else if (s1 == null) {
return -1;
} else if (s2 == null) {
return 1;
} else {
return s1.compareTo(s2);
}
});
print(list); // [null, null, a, b, c]
}
Or if you want the null at the end:
void main() {
final list = ['b', null, 'c', 'a', null];
list.sort((s1, s2) {
if (s1 == null && s2 == null) {
return 0;
} else if (s1 == null) {
return 1;
} else if (s2 == null) {
return -1;
} else {
return s1.compareTo(s2);
}
});
print(list); // [a, b, c, null, null]
}
Or, as #lrn suggests, make the last example in a more short and efficient way (but maybe not as readable :) ):
void main() {
final list = ['b', null, 'c', 'a', null];
list.sort((s1, s2) => s1 == null
? s2 == null
? 0
: 1
: s2 == null
? -1
: s1.compareTo(s2));
print(list); // [a, b, c, null, null]
}
what about _followdMusic.map((date) => return date ?? 1900.01.01).toList().sort(...)
the date is pseudo code, not sure how to write it. This way you put all unknown dates at one of the ends of the list.
The answer of #julemand101 also can be used with the extension function.
extension DateEx on DateTime? {
int compareToWithNull(DateTime? date2) {
if (this == null && date2 == null) {
return 0;
} else if (this == null) {
return -1;
} else if (date2 == null) {
return 1;
} else {
return this!.compareTo(date2);
}
}
}
Given matrices A and B the tropical product is defined to be the usual matrix product with multiplication traded out for addition and addition traded out for minimum. That is, it returns a new matrix C such that,
C_ij = minimum(A_ij, B_ij, A_i1 + B_1j, A_i2 + B_12,..., A_im + B_mj)
Given the underlying adjacency matrix A_g of a graph g, the nth "power" with respect to the tropical product represents the connections between nodes reachable in at most n steps. That is, C_ij = (A**n)_ij has value m if nodes i and j are separated by m<=n edges.
In general, given some graph with N nodes. The diameter of the graph can only be at most N; and, given a graph with diameter k, A**n = A**k for all n>k and the matrix D_ij = A**k is called the "distance matrix" entries representing the distances between all nodes in the graph.
I have written a tropical product function in chapel and I want to write a function that takes an adjacency matrix and returns the resulting distance matrix. I have tried the following approaches to no avail. Guidance in getting past these errors would be greatly appreciated!
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A == R {
return A;
} else {
tropicLimit(R,B);
}
}
which threw a domain mismatch error so I made the following edit:
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) {
return R;
} else {
tropicLimit(R,B);
}
} else {
tropicLimit(R,B);
}
}
which throws
src/MatrixOps.chpl:602: error: control reaches end of function that returns a value
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) { // Line 605 is this one
} else {
tropicLimit(R,B);
}
} else {
tropicLimit(R,B);
}
return R;
}
Brings me back to this error
src/MatrixOps.chpl:605: error: halt reached - Sparse arrays can't be zippered with anything other than their domains and sibling arrays (CS layout)
I also tried using a for loop with a break condition but that didn't work either
proc tropicLimit(B:[] real) {
var R = tropic(B,B);
for n in B.domain.dim(2) {
var S = tropic(R,B);
if S.domain != R.domain {
R = S; // Intended to just reassign the handle "R" to the contents of "S" i.o.w. destructive update of R
} else {
break;
}
}
return R;
}
Any suggestions?
src/MatrixOps.chpl:605: error: halt reached - Sparse arrays can't be zippered with anything other than their domains and sibling arrays (CS layout)
I believe you are encountering a limitation of zippering sparse arrays in the current implementation, documented in #6577.
Removing some unknowns from the equation, I believe this distilled code snippet demonstrates the issue you are encountering:
use LayoutCS;
var dom = {1..10, 1..10};
var Adom: sparse subdomain(dom) dmapped CS();
var Bdom: sparse subdomain(dom) dmapped CS();
var A: [Adom] real;
var B: [Bdom] real;
Adom += (1,1);
Bdom += (1,1);
A[1,1] = 1.0;
B[1,1] = 2.0;
writeln(A.domain == B.domain); // true
var willThisWork = && reduce (A == B);
// dang.chpl:19: error: halt reached - Sparse arrays can't be zippered with
// anything other than their domains and sibling arrays (CS layout)
As a work-around, I would suggest looping over the sparse indices after confirming the domains are equal and performing a && reduce. This is something you could wrap in a helper function, e.g.
proc main() {
var dom = {1..10, 1..10};
var Adom: sparse subdomain(dom) dmapped CS();
var Bdom: sparse subdomain(dom) dmapped CS();
var A: [Adom] real;
var B: [Bdom] real;
Adom += (1,1);
Bdom += (1,1);
A[1,1] = 1.0;
B[1,1] = 2.0;
if A.domain == B.domain {
writeln(equal(A, B));
}
}
/* Some day, this should be A.equals(B) ! */
proc equal(A: [], B: []) {
// You could also return 'false' if domains do not match
assert(A.domain == B.domain);
var s = true;
forall (i,j) in A.domain with (&& reduce s) {
s &&= (A[i,j] == B[i,j]);
}
return s;
}
src/MatrixOps.chpl:602: error: control reaches end of function that returns a value
This error is a result of not returning something in every condition. I believe you intended to do:
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) {
return R;
} else {
return tropicLimit(R,B);
}
} else {
return tropicLimit(R,B);
}
}
The following code uses a cache object outside of the factorial function. The factorial function itself is large which has too many concerns of finding factorial and caching.
How can I convert this code to a higher-order function and generate the same result when I call
console.log(factorial(5));
console.log(factorial(7));
cache = { }
function factorial(n) {
if (n === 0) {
return 1;
}
if (cache[n])
{
return cache[n];
}
console.log("Stack Up: " + n);
var value = n * factorial(n - 1);
console.log("Stack Down: " + value);
cache[n] = value;
return value;
}
console.log(factorial(5));
console.log(factorial(7));
There's already other answers out there for memoising recursive functions, but I'll adapt that answer to factorial in javascript so you can see how it works more easily
The secret to writing memoised recursive functions is continuation passing style. A similar technique works when you want to make a non-tail recursive function stack-safe.
I'll leave some console.log statements in this first example so you can see when it's actually computing and when it's just doing a memo lookup.
const memoise = f => {
const memo = new Map()
const compute = (x, k) =>
(console.log('compute', x),
memo.get(x, memo.set(x, f(x,k))))
const lookup = x =>
(console.log('lookup', x),
memo.has(x) ? memo.get(x) : compute(x, lookup))
return lookup
}
const factk = (x, k) => {
if (x === 0)
return 1
else
return x * k(x - 1)
}
const memfact = memoise(factk)
console.log(memfact(5)) // 120
console.log(memfact(7)) // 5040
Here I've removed the console.log calls inside of memoise and instead demonstrate a memoised fibonacci function vs an unmemoised one. Compare the dramatic time difference between memoise(fibk) and badfib
const memoise = f => {
const memo = new Map()
const compute = (x, k) =>
memo.get(x, memo.set(x, f(x,k)))
const lookup = x =>
memo.has(x) ? memo.get(x) : compute(x, lookup)
return lookup
}
const fibk = (x, k) => {
if (x < 2)
return x
else
return k(x - 1) + k(x - 2)
}
const badfib = x => {
if (x < 2)
return x
else
return badfib(x - 1) + badfib(x - 2)
}
console.time('memoised')
console.log(memoise (fibk) (35)) // 9227465 1.46ms
console.timeEnd('memoised')
console.time('unmemoised')
console.log(badfib(35)) // 9227465 135.85ms
console.timeEnd('unmemoised')
Is it possible to somehow configure bundle to generate images also for retina display, like #2x?
Or can someone give me an advice how to deal with retina?
Thanks
According to this comment by nahakiole, there are 2 solutions for this:
You can either use the picture element which would provide the syntax
to declare multiple sources for an image.
http://w3c.github.io/html/semantics-embedded-content.html#the-picture-element
The other method which we've tried was, if you can guarantee that the
image exists, to use a modified version of the retina.js which adds
_retina to the filter name and checks if a image with this name exists.
Modified version of retina.js by nahakiole:
/*-----------------------------------------------------------------------------------*/
/* RETINA.JS
/*-----------------------------------------------------------------------------------*/
(function () {
var regex = /(media\/cache\/filter_[A-Z]+)/i //Added this
function t(e) {
this.path = e;
var t = this.path.split("."),
n = t.slice(0, t.length - 1).join("."),
r = t[t.length - 1];
this.at_2x_path = (n + '.' + r).replace(regex, '$1_retina') //Changed that
}
function n(e) {
this.el = e, this.path = new t(this.el.getAttribute("src"));
var n = this;
this.path.check_2x_variant(function (e) {
e && n.swap()
})
}
var e = typeof exports == "undefined" ? window : exports;
e.RetinaImagePath = t, t.confirmed_paths = [], t.prototype.is_external = function () {
return !!this.path.match(/^https?\:/i) && !this.path.match("//" + document.domain)
}, t.prototype.check_2x_variant = function (e) {
var n, r = this;
if (this.is_external()) return e(!1);
if (this.at_2x_path in t.confirmed_paths) return e(!0);
n = new XMLHttpRequest, n.open("HEAD", this.at_2x_path), n.onreadystatechange = function () {
return n.readyState != 4 ? e(!1) : n.status >= 200 && n.status <= 399 ? (t.confirmed_paths.push(r.at_2x_path), e(!0)) : e(!1)
}, n.send()
}, e.RetinaImage = n, n.prototype.swap = function (e) {
function n() {
t.el.complete ? (t.el.setAttribute("width", t.el.offsetWidth), t.el.setAttribute("height", t.el.offsetHeight), t.el.setAttribute("src", e)) : setTimeout(n, 5)
}
typeof e == "undefined" && (e = this.path.at_2x_path);
var t = this;
n()
}, e.devicePixelRatio > 1 && (window.onload = function () {
var e = document.getElementsByTagName("img"),
t = [],
r, i;
for (r = 0; r < e.length; r++) i = e[r], t.push(new n(i))
})
})();
I created a variable q outside of any function. From within my function I am attempting to simply increment it with a ++. Will this increment the global q or is this simply appending the value to a local variable? As you can see in the code sample below I am attempting to use the value of the global variable (which I intend to be updated during each execution of this script) to set a variable which should trigger this function via .change. The function is initially trigger (when q = 1) however it is not trigger when a selection is made from the dropdown box with id = "selectedId2" which is leading me to believe that q has retained a value of 1 though I successfully incremented it when the function was ran prior. Any advise of how I can increment the variable "q" for each iteration of this script would be greatly appreciated.
if (q === 1) {
selectedDiv = '#selectId1';
selectedDiv2 = '#selectId2';
}
if (q === 2) {
selectedDiv = '#selectedId2';
selectedDiv2 = '#selectedId3';
}
if (q === 3) {
selectedDiv = '#selectedId3';
selectedDiv2 = '#selectedId4';
}
if (q === 4) {
selectedDiv = '#selectedId4';
selectedDiv2 = '#selectedId5';
}
if (q === 5) {
selectedDiv = '#selectedId5';
selectedDiv2 = '#selectedId6';
}
$(selectedDiv).change(function () {
if (q == 1) {
var pullDownDivs = '#2';
}
if (q == 2) {
var pullDownDivs = '#3';
}
if (q == 3) {
var pullDownDivs = '#4';
}
if (dropDownSelectJoined != null) {
var dropDownSelectJoined = dropDownSelectJoined + ", " + $(selectedDiv).val();
}
else {
var dropDownSelectJoined = $(selectedDiv).val();
}
var SelArea = $(selectedDiv).val();
if (SelArea != 0) {
var url = '#Url.Action("NetworkSubForm")';
q++;
$.post(url, { RemovedAreaId: $('#RemovedAreaId').val(), selectedNetworkId: $('#SelectedNetworkId').val(), dropDownSelectJoined: dropDownSelectJoined },
function (data) {
var productDropdown = $(selectedDiv2);
productDropdown.empty();
productDropdown.append("<option>-- Select Area --</option>");
for (var i = 0; i < data.length; i++) {
productDropdown.append($('<option></option>').val(data[i].Value).html(data[i].Text));
}
});
$(pullDownDivs).show();
$(pullDownDivs).html();
}
else {
$(pullDownDivs).hide();
$(pullDownDivs).html();
}
});
I don't know what the rest of your code looks like, but you can see this kind of behavior due to "shadowing":
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
q++;
console.log(q);
}
Repeatedly calling handler will output 1 each time since you are redefining a local q within handler. However, the outer q remains unchanged. But if you did this:
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
window.q++;
console.log(window.q);
}
The global q will be updated since you are explicitly referencing it by doing window.q.