I have
init:
test: yasha,grisha
my: ${init.test[0]}
And it's now working.
How work with list/arrays in YAML?
A list in YAML (normally called a sequence) can be specified in in block style:
a:
- 1
- 2
and flow style:
a: [1, 2]
both depicting a mapping with one key a, for which the value is the sequence/list consisting of elements 1 and 2
The dashes before the elements in block style can, but do not have to be, indented further than the "parent" element
Related
What does this do, and is there a simpler way to write it?
Collection>>into: a2block
| all pair |
all := ([:allIn :each| allIn key key: allIn value. each])
-> (pair := nil -> a2block).
pair key: all.
self inject: all
into: [:allIn :each| allIn value: (allIn key value: allIn value value: each). allIn].
^all value
If you want to find out, the best way is to try it, possibly step by step thru debugger.
For example, try:
(1 to: 4) into: #+.
(1 to: 4) into: #*.
You'll see a form of reduction.
So it's like inject:into: but without injecting anything.
The a2block will consume first two elements, then result of this and 3rd element, etc...
So we must understand the selector name as inject:into: without inject:: like the implementation, it's already a crooked way to name things.
This is implemented in Squeak as reduce:, except that reduce: would be well too obvious as a selector, and except that it would raise an Error if sent to an empty collection, contrarily to this which will answer the strange recursive artifact.
The all artifact contains a block to be executed for reduction as key, and current value of reduction as value. At first step, it arranges to replace the block to be executed with a2block, and the first value by first element. But the recursive structure used to achieve the replacement is... un-necessarily complex.
A bit less obfuscated way to write the same thing would be:
into: a2block
| block |
self ifEmpty: [self error: 'receiver of into: shall not be empty'].
block := [:newBlock :each| block := newBlock. each].
^self inject: a2block into: [:accum :each| block value: accum value: each]
That's more or less the same principle: at first iteration, the block is replaced by the reduction block (a2block), and first element is accumulated.
The reduction only begins at 2nd iteration.
The alternative is to check for first iteration inside the loop... One way to do it:
into: a2block
| first |
self ifEmpty: [self error: 'receiver of into: shall not be empty'].
first := Object new.
^self inject: first into: [:accum :each |
accum == first
ifTrue: [each]
ifFalse: [a2block value: accum value: each]].
There are many other ways to write it, more explicitely using a boolean to test for first iteration...
I am quite new to XQuery and I am trying to get a list of all elements and all attributes.
It should look like this:
element1 #attributex, #attribue y, ...
element 2 #attribute x, #attribute y, ...
element 3 #attribute x, #attribute y, ...
I am trying this so far, but the error "Item expected, sequence found":
for $x in collection("XYZ")
let $att := local-name(//#*)
let $ele := local-name(//*)
let $eleatt := string-join($ele, $att)
return $eleatt
I feel like I am turning an easy step into a complicated one. Please help.
Thanks in advance, Eleonore
//#* gives you a sequence of attribute nodes, //* a sequence of element nodes. In general to apply a function like local-name() to each item in a sequence, for nodes you have three options:
Use a final step /local-name() e.g. //#*/local-name() or //*/local-name()
In XQuery 3.1 use the map operator ! e.g. //#*!local-name()
Use a for .. return expression e.g. for $att in //#* return local-name($att)
The local-name() function takes a single node as its argument, not a sequence of nodes. To apply the same function to every node in a sequence, using the "!" operator: //*!local-name().
The string-join() function takes two arguments, a list of strings, and a separator. You're trying to pass two lists of strings. You want
string-join((//*!local-name(), //#*!local-name()), ',')
Of course you might also want to de-duplicate the list using distinct-values(), and to distinguish element from attribute names, or to associate attribute names with the element they appear on. That's all eminently possible. But for that, you'll have to ask a more precise question.
I have an array of elements that I supply for a vue component as a reactive data source (I'm inspecting the data with the vue chrome extension):
the view: [A,B,C,D,E]
the data: [A,B,C,D,E]
I want to move an item (D) to a new position (before B), so first I remove the element with splice, then reinsert it at the desired index:
the view: [A,D,B,C,E]
the data: [A,B,C,D,E]
So when I hover over in the Chrome Vue inspector over the second component, in the view the third column gets highlighted. If I hover over the 3rd element in the data, in the view the 4th element get highlighted, and so on.
The view updates correctly, but I want underlying the data to follow it.
In the array the elements are objects.
I guess this is because they are passed as reference?
I think I've found it, instead of splice I should use set and remove on the vue instance:
https://v2.vuejs.org/v2/api/#Vue-set
You should avoid directly setting elements of a data-bound Array with
indices, because those changes will not be picked up by Vue.js.
Instead, use the augmented $set() method
I had the same issue as well, what happened was I didn't use unique key values for each vue object in the array. I used the index in the array as the key. So when items were resorted, some of the data would be binded to different items because keys were swapped.
What I used was a Date.now() function to initialize a UUID to set for each key
So for instance, say we had the key set to the index of the array
[ 0, 1, 2, 3, 4] - The keys
[A0,B0,C0,D0,E0] - The array of objects
[A1,B1,C1,D1,E1] - The data attribute inside each of the objects in array
So [A0] has a key of [0], and data attribute of [A1].
Say we swap [A0] and [B0]
[ 0, 1, 2, 3, 4] - the key
[B0,A0,C0,D0,E0] - the array of objects
[A1,B1,C1,D1,E1] - the data attribute assigned to each object in array
Now [A0] is binded to the data attribute of [B1], because
[B1] is binded to the key of [1] and A[0] key is [1]
This is never what you want, so you want to make each key unique instead. A common way of doing this is using a Date.now() method upon data initialization, or a create a UUID
In Summary
Example in Vue for creating a unique UUID for each object when using vue methods
methods: {
_addGroup: function() {
let result = {
sortId: this.wizardGroups.length + 1,
text: 'Hello world'
uuid: Date.now(),
};
this.wizardGroups.push(result);
}
Assign that value to the key during v-for iteration
<child-component
v-for="wizardGroup in wizardGroups"
:key="wizardGroup.uuid">
</child-component>
Although it seems fairly simple, there is a small nuance to the obvious solution.
The following code would cover most situations:
arr_1=(1 2 3 4)
arr_2=($arr_1)
However, empty strings do not copy over. The following code:
arr_1=('' '' 3 4)
arr_2=($arr_1)
print -l \
"Array 1 size: $#arr_1" \
"Array 2 size: $#arr_2"
will yield:
Array 1 size: 4
Array 2 size: 2
How would I go about getting a true copy of an array?
It would be an "Array Subscripts" issue, so you could properly specify an array subscript form to select all elements of an array ($arr_1 for instance) within double quotes:
arr_1=('' '' 3 4)
arr_2=("${arr_1[#]}")
#=> arr_2=("" "" "3" "4")
Each elements of $arr_1 would be properly surrounded with double quotes even if it is empty.
A subscript of the form ‘[*]’ or ‘[#]’ evaluates to all elements of an array; there is no difference between the two except when they appear within double quotes.
‘"$foo[*]"’ evaluates to ‘"$foo[1] $foo[2] ..."’, whereas ‘"$foo[#]"’ evaluates to ‘"$foo[1]" "$foo[2]" ...’.
...
When an array parameter is referenced as ‘$name’ (with no subscript) it evaluates to ‘$name[*]’,
-- Array Subscripts, zshparam(1)
And empty elements of arrays will be removed according to "Empty argument removal", so
arr_2=($arr_1)
#=> arr_2=(${arr_1[*]})
#=> arr_2=(3 4)
Above behavior is not good in this case.
24. Empty argument removal
If the substitution does not appear in double quotes, any resulting zero-length argument, whether from a scalar or an element of an array, is elided from the list of arguments inserted into the command line.
-- Empty argument removal, Rules Expansion zshexpn(1)
I need to implement a linked list in ADA that has a node of 3 parts that include:
1. name of the node
2. value of the node
3. name of the next node
I need to take inputs from user, with each part of the node ending with a ";"
e.g
This is what input on command line must look like
a;22;b
b;33;c
c;43
The LL ends at c. So we have nothing after the value
I can implement a LL, but how am I supposed to read the ';' in the input and assign it to the respective node dynamically to build the linked list???
Assuming you have a string Input which contains one of your nodes' data (for example, ”a;22;b”), you can find the position of the first semicolon using
First_Semicolon : Natural :=
Ada.Strings.Fixed.Index (Source => Input,
Pattern => ";”,
From => Input'First);
and the last semicolon using
Last_Semicolon : Natural :=
Ada.Strings.Fixed.Index (Source => Input,
Pattern => ";",
From => Input'Last,
Going => Ada.Strings.Backward);
The node Name is then the substring of input from the beginning to one before the first semicolon,
Input (Input'First .. First_Semicolon - 1)
If First_Semicolon and Last_Semicolon are equal, then you have the case where there’s no next node name, and the node Value is
Natural'Value (Input (First_Semicolon + 1 .. Input'Last))
but if they aren’t equal the next node name is present, so the node Value comes from the part of Input between the semicolons,
Natural'Value (Input (First_Semicolon + 1 .. Last_Semicolon - 1))
and the Next_Node_Name from the remainder of Input,
Input (Last_Semicolon + 1 .. Input’Last)
Obviously there’s no error checking here, and there’s a lot that could go wrong. I’ve not discussed creating the linked list, either, because you say you can do that (personally I’d use Ada.Containers.Doubly_Linked_Lists ...)