$hash_arr_1 = { b => 2, c => 3, f => 1 }
$arr = ['a', 'c', 'd', 'f', 'e']
$hash_arr_2 = $arr.map |$param| {
if has_key($hash_arr_1, $param) {
{$param => $hash_arr_1[$param]}
}
}
notice($hash_arr_2)
Result: [{ , c => 3, , f => 1, ,}]
How to do that there are no empty elements in the array?
The problem here is that you are using the map lambda function when really you want to be using filter. Summary from linked documentation is as follows:
Applies a lambda to every value in a data structure and returns an array or hash containing any elements for which the lambda evaluates to true.
So the solution for you is:
$hash_arr_2 = $hash_arr_1.filter |$key, $value| { $key in $arr }
This will iterate through the keys of the hash $hash_arr_1, check if the key exists as a member of the array $arr with the provided conditional, and then return a hash with only the key value pairs that evaluated to true.
Related
I have the following list of dictionaries, with sub dictionaries data:
data2 = [
{"dep": None},
{"dep": {
"eid": "b3ca7ddc-0d0b-4932-816b-e74040a770ec",
"nid": "fae15b05-e869-4403-ae80-6e8892a9dbde",
}
},
{"dep": None},
{"dep": {
"eid": "c3bcaef7-e3b0-40b6-8ad6-cbdb35cd18ed",
"nid": "6a79c93f-286c-4133-b620-66d35389480f",
}
},
]
And I have a match key:
match_key = "b3ca7ddc-0d0b-4932-816b-e74040a770ec"
And I want to see if any sub dictionaries of each "dep" key in data2 have an eid that matches my match_key. I'm trying the following, but I get a TypeError: string indices must be integers - where am I going wrong?
My Code
matches = [
d["eid"]
for item in data2
if item["dep"]
for d in item["dep"]
if d["eid"] == match_key
]
So matches should return:
["b3ca7ddc-0d0b-4932-816b-e74040a770ec"]
Meaning it found this id in data2.
When you iterate over a dictionary, each iteration gives you a key from the dictionary.
So d["eid"] is actually "eid"["eid"], which is an invalid expression. That's why Python raises the following exception:
TypeError: string indices must be integers
Also, the expression d["eid"] assumes that every d contains the eid key. If it doesn't, Python will raise a KeyError.
If you don't know for sure that "eid" is a valid key in the dictionary, prefer using the .get method instead.
matches = [
v
for item in data2
if item.get("dep") # Is there a key called dep, and it has a non-falsy value in it
for k, v in item["dep"].items() # Iterate over the dictionary items
if k == "eid" and v == match_key
]
You can do even better by directly accessing the value of eid key:
matches = [
d["dep"]["eid"]
for d in data2
if d.get("dep") and d["dep"].get("eid") == match_key
]
I'm iterating over a vector of chars. I would like to detect specific sequences of chars ("ab", "cd", "pq" and "xy"). If I find one of these, I want to return false. However if I find a double letter sequence (e.g: "aa"), I want to return true.
I came up with this:
let chars: Vec<char> = line.chars().collect();
for (idx, c) in chars.iter().enumerate() {
if idx > 0 {
match (chars[idx - 1], c) {
('a', 'b') => return false,
('c', 'd') => return false,
('p', 'q') => return false,
('x', 'y') => return false,
(c, c) => return true,
_ => (),
};
}
However when I run this I get the following error:
36 | (c, c) => return true,
| ^ used in a pattern more than once
and I can't understand why.
running rustc --explain E0416 seems to give a solution:
match (chars[idx - 1], c) {
('a', 'b') => return false,
('c', 'd') => return false,
('p', 'q') => return false,
('x', 'y') => return false,
(prev, curr) if &prev == curr => return true,
_ => (),
};
But I would like to understand what's happening here. I'd have expected the equality check to happen with (c, c).
From the documentation:
To create a match expression that compares the values of the outer x and y, rather than introducing a shadowed variable, we would need to use a match guard conditional
The match pattern needs a literal here, or the declaration of new variables, you can't just put another dynamic value to compare with.
You can use the solution given by the compiler, or the more direct
(a, _) if a==*c => return true,
Note that there are ways to avoid collecting into a vector here. You could for example store the previous value in a mutable variable of type char (by taking the first value before the loop if you know the string isn't empty) or into an Option<char>.
So suppose there are two lists
var parsedList = ['a','b','c','d']
var originalList = ['a#','c#','h#']
And I would like to return a subset of originalList which contains values in the parsedList. (e.g. ['a#','c#'] as 'a' and 'c' is in the parsedList) Is there a simple and elegant way to do this?
This approach is very straightforward and elegant, first you loop over your originalList
and then for each element in that array, you want to check if parsedList includes it or not, and you can do that with parseList.includes()
var parsedList = ['a','b','c','d']
var originalList = ['a','c','h']
let newArr = []
originalList.forEach(element => {
if (parsedList.includes(element)){
newArr.push(element)
}
})
console.log(newArr) // ['a', 'c']
do you want something like that or you want to editoriginalList ?
in case you want it in the same array
originalList = originalList.filter(element => {
return parsedList.includes(element)
})
console.log(originalList) // ['a', 'c']
how to insert character from array?
This my data :
["a", "b", "c", ...]
i'm wanna change my data like this:
["$a", "$b", "$c", ...]
Thanks before
let a = ["a", "b", "c", ...]
a.map(value => '$'+value) // this will do what you need returns ["$a", "$b", "$c"]
map basically iterate through the array and map each element according to the given condition
Array.map(value => map the value with any type of data here)
Use map - ES6 way
Map mdn
const arr = ['a', 'b']
const modifiedArray = arr.map(el => '$' + el)
console.log(modifiedArray)
However note it will modify the original array so if you don't want to modify original array
Use spread of ES6
spread mdn
const modifiedArray = {...arr}.map(el => '$' + el)
Non ES6
var arr = ['a', 'b'],
modifiedArr = []
for(let i=0; i < arr.length; i++) {
modifiedArr.push('$' + arr[i])
}
console.log(modifiedArr)
I have dictionary
Output = [a:2, c:13, b:5, z:'Test']
I use for loop as follows
for(i in Output){
println(Output[i.key]);
}
it is result.
2
13
5
Test
but I expect result (reverse).
Test
5
13
2
Could you please help me?
What you have is not a "dictionary" (this is not Python), but a Map.
The order of its entries is not defined it is just a mapping key to value without any ordering. The order you get is (pseudo-)random and can not be depended upon.
Btw. the more Groovy way for producing the output would be to not use a for-loop, but e. g.
[a:2, c:13, b:5, z:'Test'].values().each { println it }
If you want to have an order, you need a list instead of a map, e. g. like a list of maps as in
[[a:2], [c:13], [b:5], [z:'Test']].reverse().collectMany { it.values() }.each { println it }
or a list of lists as in
[['a', 2], ['c', 13], ['b', 5], ['z', 'Test']].reverse().collect { it[1] }.each { println it }
or maybe this list of maps which probably would be the cleanest of these solutions
[[key:'a', value:2], [key:'c', value:13], [key:'b', value:5], [key:'z', value:'Test']].reverse().collect { it.value }.each { println it }