Unique filter in Nunjuck - nunjucks

systems:
- name: Fred
country: DE
- name: Wilma
country: US
- name: Pebbles
country: DE
- name: Dino
country: US
---
# Systems
Countries: {{ page.systems | join(",", "country") }}
I am trying to create a GitBook page with a list of items containing no duplicates. I.e I would want to apply a 'unique' filter or 'distinct' filter in my Nunjucks template for the page. The template needs to process the page variables (YAML). The above template generates the output:
Countries: DE,US,DE,US
I would like it to produce the output
Countries: DE,US
How could I achive that? (Given that 'unique' filter is not supported with Nunjucks.)

You can extend your Nunjucks through Custom filter
const nunjucks = require('nunjucks');
const env = new nunjucks.Environment(/* loaders etc... */);
env.addFilter('unique', arr => arr instanceof Array && arr.filter((e, i, arr) => arr.indexOf(e) == i) || arr);
let out = env.renderString(`{{[1, 2, 3, 2] | unique }}`);
console.log(out);

Related

yq select entry value based on subkey

Using yq (v4.25.3), and considering the following yaml file
accounts:
- account_id: 'XXXXXXXX'
name: sandbox
deploy_iam: true
role: arn:aws:iam::XXXXXXXX:role/iam_role
regions:
- all
- account_id: 'YYYYYYY'
name: dev
deploy_iam: true
role: arn:aws:iam::YYYYYYY:role/iam_role
regions:
- all
Is it possible to get the value of the deploy_iam attribute given an account_id value?
I can get the list of account_id with
yq '.accounts[].account_id' < accounts.yml
And I tried to filter using with_entries
yq '.accounts[].account_id |= with_entries(select(.key == "XXXXXXXX"))' < accounts.yml
Without luck so far.
Any idea?
With mikfarah/yq it should be pretty straightforward. Select the required object with the select() expression and access the required field with the dot notation
yq '.accounts[] | select(.account_id == "XXXXXXXX").deploy_iam' < accounts.yml

How do I add a map to an array of maps in ytt?

I'm trying to add a map to an array of maps in ytt to modify a YAML doc.
I tried the below but it errors out and says it expects a map but getting an array.
https://gist.github.com/amalagaura/c8b5c7c92402120ed76dec95dfafb276
---
id: 1
type: book
awards:
books:
- id: 1
title: International Botev
reviewers:
- id: 2
name: PersonB
- id: 2
title: Dayton Literary Peace Prize
reviewers:
- id: 3
name: PersonC
#! How do I add a map to an array of maps?
## load("#ytt:overlay", "overlay")
##overlay/match by=overlay.all
---
awards:
books:
##overlay/match by=overlay.all, expects="1+"
##overlay/match missing_ok=True
reviewers:
##overlay/append
- id: 1
name: PersonA
## load("#ytt:overlay", "overlay")
#! Add a map to an array of maps:
##overlay/match by=overlay.all
---
awards:
books:
##overlay/match by=overlay.all, expects="1+"
- reviewers:
##overlay/append
- id: 1
name: Person A
You were really close in your solution, all you really needed was to make reviewers an array item. If you want to be able to add reviewers to a book that does not have that key, then you will have to add a matcher on the array item and the map item; a gist is included below to see this behavior overlay in action.
If you have more than one ##overlay/match annotation on the same item, the last one wins. There are plans to improve this behavior: https://github.com/k14s/ytt/issues/114.
https://get-ytt.io/#gist:https://gist.github.com/gcheadle-vmware/a6243ee73fa5cc139dba870690eb15c5

Ask about rxjs' use of Obsevable distinct

I want to know how to use Observable.
What I want to do is duplicate deletion. The following sample 1 can be moved, but what I want to do is not this format, but how to cook when preparing an array in advance.
orgLayerDistinct(allList: LabelMasterExt[]) {
// Observable.of( allList ).distinct( );
// [sample 1] このサンプルは動くが好みの形式ではない。
// [sample 1] This sample works, but it's not a form of favorite.
Observable.of<Person>(
{ age: 4, name: 'Foo'},
{ age: 7, name: 'Bar'},
{ age: 5, name: 'Foo'},
{ age: 6, name: 'Foo'})
.distinct((p: Person) => p.name)
.subscribe(x => console.log(x));
// [sample 2 experimental] 配列を用意してある前提で利用したい。
// [sample 2 experimental] I would like to use an array on the assumption that it is prepared.
const persons: Person[] = [];
persons.push({ age: 4, name: 'Foo'});
persons.push({ age: 7, name: 'Bar'});
persons.push({ age: 5, name: 'Foo'});
persons.push({ age: 6, name: 'Foo'});
Observable.of<Person[]>(persons)
.distinct((p: Person) => p.name)
.subscribe(x => console.log(x));
}
[sample 2 experimental]
However, this gives the following error.
The type argument for type parameter 'T' cannot be inferred from the usage.
Consider specifying the type arguments explicitly.
Type argument candidate 'Person[]' is not a valid type argument
because it is not a supertype of candidate 'Person'.
Property 'includes' is missing in type 'Person'.
Is there any good plan?
You can either use Observable.from<Person>(array) or Observable.of<Person>(...array).
The problem your second example has is that Observable.of<Person[]>()s elements are arrays of Person, but the .distinct() is expecting an input of the Person type.

PouchDB: filtering, ordering and paging

Very similar to these two CouchDB questions: 3311225 and 8924793, except that these approaches don't allow partial matching. Having e.g. these entries:
[{_id: 1, status: 'NEW', name: 'a'},
{_id: 2, status: 'NEW', name: 'aab'},
{_id: 3, status: 'NEW', name: 'ab'},
{_id: 4, status: 'NEW', name: 'aaa'},
{_id: 5, status: 'NEW', name: 'aa'}]
and key
[status, name, _id]
There seems to be no way to
filter these entries by status (full string match) and name (partial string match ~ startsWith)
order them by id
paginate them
because of the partial string match on name. The high value unicode character \uffff that allows this partial match also causes to ignore the _id part of the key, meaning the resulting entries are not sorted by _id, but rather by status and name.
var status = 'NEW';
var name = 'aa'
var query = {
startkey: [status, name],
endkey: [status, name + '\uffff', {}],
skip: 0,
limit: 10
};
results in
[{_id: 5, status: 'NEW', name: 'aa'},
{_id: 4, status: 'NEW', name: 'aaa'},
{_id: 2, status: 'NEW', name: 'aab'}]
There is no option to sort in memory, as this would only sort the individual pages, and not the entire data set. Any ideas about this?

How to I reference an array member in Ruby?

Given this array in Ruby:
myarray = [name: "John", age: 35]
How do I refer to the age?
I tried myarray[:age] but got an error can't convert Symbol into Integer
Update:
I was trying to simplify my question by extracting what I thought my problem is. I may not understand completely.
I'm experimenting with Dashing and trying to send a number to a meter widget. I've created a variable, 'response_raw' and am trying to send it in the third send event. Here's my code:
SCHEDULER.every '1m', :first_in => 0 do
# Get checks
url = "https://#{CGI::escape user}:#{CGI::escape password}#api.pingdom.com/api/2.0/checks"
`enter code here`response = RestClient.get(url, {"App-Key" => api_key})
response = JSON.parse(response.body, :symbolize_names => true)
if response[:checks]
checks = response[:checks].map { |check|
if check[:status] == 'up'
state = 'up'
last_response_time = "#{check[:lastresponsetime]}ms"
response_raw = check[:lastresponsetime]
else
state = 'down'
last_response_time = "DOWN"
response_raw = 0
end
{ name: check[:name], state: state, lastRepsonseTime: last_response_time, pt: response_raw }
}
else
checks = [name: "pingdom", state: "down", lastRepsonseTime: "-", pt: 0]
end
checks.sort_by { |check| check['name'] }
send_event('pingdom', { checks: checks })
send_event('pingdom-meter', { value: checks[:pt] })
end
In CoffeeScript [name: "John", age: 35] is an array containing single object with two properties (name and age).
Here is how it'll look in plain JavaScript:
myarray = [
{
name: "John",
age: 35
}
];
So, answering your question, to access an age you should take the first element of an array and then reference an age property:
myarray[0].age
or
myarray[0]['age']
But, judging from your question, your're probably using wrong data structure. Why don't you want to use a plain object instead of an array?
person = name: "John", age: 35
console.log "#{person.name}'s age is #{person.age}"
Update
It looks like your question is actually about Ruby and not about CoffeeScript. Though, my answer will remain the same.
To access an age you should take the first element of an array and then reference an age property:
myarray[0][:age]
Since myarray is an array, Ruby expects an integer index, but you're giving it symbol :age instead.
I finally figured it out with Leonid's help. Thank you.
I changed:
send_event('pingdom-meter', { value: checks[:pt] })
to
send_event('pingdom-meter', { value: checks[0][:pt] })

Resources