Q语言while循环问题:递增id调用函数f直至生成长度为1的表
Great question! The problem with your current approach is that you’re passing the table output of f directly into the next iteration of f—but f expects an integer id parameter, not a table. Let’s adjust this by focusing our iteration on the id itself instead of the table.
First, let’s recap your function definition for clarity:
f:{[id] len:(1?1 2 3 4 5)0; ([] identifier:id+til len; c2:len?`a`b`c)}
Method 1: Iterate over the ID (two-step solution)
The repeat adverb (/) works by applying a function repeatedly to an initial value as long as a condition is true. Here’s how to use it to track the incrementing id:
- Define the stop condition: we keep looping as long as the table from
f[id]has more than 1 row:shouldContinue: {(count f[x]) > 1} - Define the iteration step: increment the
idby 1 each time:incrementId: {x + 1} - Use the repeat adverb to find the first
idwheref[id]returns a table of length 1:finalValidId: shouldContinue incrementId/ 0; - Call
fwith this valididto get your result:result: f[finalValidId];
Method 2: Single-step repeat call (return the table directly)
If you want to skip the separate finalValidId step, you can write a function that either returns the next id (if we need to keep going) or the final table (when we’re done). We’ll adjust the condition to check if we’re still working with an integer id:
result: {type[x] = -6h} // Check if input is an integer (Q's int type code is -6h) {[x] t: f[x]; $[count t > 1; x + 1; t] // Return next id if we need to keep going, else the table }/ 0;
This iteration stops as soon as we return a table (not an integer), and that table is your final result.
Why your original code failed
Your line {(count x)>1} f/0 takes the table returned by f[0] and passes it as the input to the next call of f. But f needs an integer id—so the second call would try to run f[<table>], which breaks because you can’t add a table to til len. By iterating over the id instead, we ensure f always gets a valid input.
内容的提问来源于stack exchange,提问作者tenticon

