简体   繁体   中英

What is the best way to iterate over a Hash in KRL?

Let's say I have a hash where I don't know the contents of the hash (so I can't use pick for this). Here is an example of the hash:

{ "key1" : "value1", "key2" : "value2", "key3" : "value3" }

I want to iterate over this hash and create the following array:

["key1=value1", "key2=value2", "key3=value3"]

My first approach would be to build a recursive function that iterates through the hash and populates the array, but I'm not sure if that can be done. In an array, I can use head() and tail() to help with the recursion, but those operators aren't available for a hash (as far as I know).

I want to initiate this from within a function because I'm doing this in a module. For example:

hash_to_array = function(h) {
  // magic code here
}

manipulate_params = function(params) {
  params_array = hash_to_array(params);
  // more code here...

}

Mike, after impact, I will carve out time to build a keys() operator for hashes.

In the meantime, what I have done to get around this is to keep a separate array of the keys. That way, I can use map, filter and all of the set operations on the index and then use the those values as my keys for the hash operations

key_array = ["key1","key2","key3"];
my_hash = { "key1" : "value1", "key2" : "value2", "key3" : "value3" };

This really only works if you are controlling the values in the hash, but here is some example code:

global {
    kvHash = { "key1" : "value1", "key2" : "value2", "key3" : "value3" };
    kArray = ["key1","key2","key3"];
  }

pre {
        pickKey = kArray[1];
        value = kvHash.pick("$.#{pickKey}");
        // add a new value
        newKey = "key4";
        newVal = "value4";
        newArray = kArray.union(newKey);
        newHash = kvHash.put([newKey],newVal);
}

Noticed that I used the set operator union to keep the array full of unique values

The javascript that is generated shows what this does:

var pickKey = 'key2';
var value = 'value2';
var newKey = 'key4';
var newVal = 'value4';
var newArray = ['key1', 'key2', 'key3', 'key4'];
var newHash = {'key2' :'value2','key1' :'value1','key4' :'value4','key3' :'value3'};

Now, you can use the map or filter operators to pass each value individually to a function

c.map(function(x){x+2})

c.filter(function(x){x<5})

I'll suggest this:

foreach my_hash setting(key, value)
pre {
  my_array.push("#{key}=#{value}");
}

See http://docs.kynetx.com/docs/Select

I believe I've figured this out, but the answer is a little bit of a hack.

hash_to_sorted_array = function(params, names, new_a) {
  n = names.head();
  val = params.pick("$.#{n}", true);
  appended_array = new_a.append("#{n}=#{val.head()}");      
  finished_array = (names.length() == 0) => new_a |
                   hash_to_sorted_array(params, names.tail(), appended_array);      
  finished_array.sort()
}

This recursive function iterates over the names array, which contains the keys in the hash and removes the key that it processes in each iteration.

To call this function, just call:

sorted_array = hash_to_sorted_array(params, names, []);

For those unfamiliar with the head() and tail() methods of an array: head() gives you the first element in the array while tail() gives you a new array with the first element removed.

I don't really love this solution because you have to pass the names, or the keys, of the hash into the function as one of the arguments. As of this writing, I don't know of any way to extract just the keys from a hash, or I would just use that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM