-
Notifications
You must be signed in to change notification settings - Fork 445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove a field from an object #312
Comments
std.objectFieldsAll(o) will return the hidden ones too. However all your hidden fields would become visible because of the : in { [f]: v for f in std.objectFieldsAll(o) } |
Can you get the effect of removing a field just by marking it as hidden? x :: super.x |
Is there any chance that dict comprehension can include to use hidden too? |
One thing I'd like to do is generalize the object comprehension and merge it with the object literal. This means things like this will be possible:
There's another request in #90 to extend comprehensions. What you can do is then:
|
It's quite easy from that to build it with all fields except one, just put if k != "foo" at the end. |
This isn't strictly the same as removing a field from an object though, what it's doing is creating a statically bound copy. E.g. if we took the above code and put it in a function clone(), then:
would yield:
|
@sparkprime Yes, extending object comprehension and with hidden field would solve this issue.
|
Unfortunately, the object is not late bound anymore in this case. |
@mbarbero That said, |
Indeed, it's still useful. My comment was a bit "raw", sorry about that. I just wanted to note that, if jsonnet ever includes a solution to remove fields from an object, it would be great if the solution would retain the late bounding on target object. |
I've just realized that the proposed implementation of
And that loses the visibility information. |
I just ran into this, finding that If the # of replicas is managed by a Horizontal Pod Autoscaler, then you want to ensure that you don't change the # of replicas each time you deploy. |
could you do something like:
? |
Not really. The comprehensions only support a single field pattern. Also you can't wrap the fields in ifs like that. If you have a proposition how that could work, we can look into it. Right now you can do it with two comprehensions (one for Perhaps a more direct way of handling this, would be to just add a builtin to remove a field. We would need to specify what it means for self and super. I'm also open to proposals. Generally, I would recommend removing fields only for "plain" objects anyway and you care only about what fields evaluate to and not automagically maintaining relationships between them. By plain objects I mean objects where each field is visible and concrete (i.e. doesn't depend on other fields through self/super). In such case |
I really expected something like CSS's |
Years ago I thought about adding the facility to remove a field in a mixin. The syntax might look like that, or maybe |
What do you mean right now? I can't do |
@frimik |
Deconstruction proposal partially (this/super becomes frozen) solves this issue: #307 local sourceObject = {
a: 1,
b: 2,
c:: 3,
fieldToOmit: 4,
};
local {
fieldToOmit: ?,
...targetObject
} = sourceObject;
std.manifestJson(targetObject) == '{"a": 1, "b": 2}' |
I started using Now I changed methods to using local ddMergePatch = {
[k]: null
for k in std.objectFields(agent.datadog)
if std.objectHas(agent.datadog[k], 'kind') && agent.datadog[k].kind != 'PodSecurityPolicy'
};
local agentMergePatch = {
[k]: null
for k in std.objectFields(agent)
if std.objectHas(agent[k], 'kind') && agent[k].kind != 'PodSecurityPolicy'
};
std.mergePatch(agent, agentMergePatch) {
datadog: std.mergePatch(agent.datadog, ddMergePatch),
},
|
I saw Jrsonnet mentioned in this thread, and they do support this:
You do have to build it yourself though to get this functionality, but looks promising. |
Also, on the topic of object comprehensions and for loops. Recursive functions does not have this issue. I ended up creating my own forEach/map function: https://github.com/dxlr8r/dxsonnet/blob/main/lib/obj.libsonnet With a function like that in place, it is simple to create for example a pop function, which can then be called like this:
|
Hey there, I went with this approach which allows multiple fields to be ignored. In my {
// Function to filter an object by excluding specified fields.
// Parameters:
// - inputObject: The object to be filtered.
// - fieldsToIgnore: List of fields to be ignored from the input object.
filterObjectFields(inputObject, fieldsToIgnore)::
// Iterating over the fields in the input object and creating a new object
// without the fields specified in `fieldsToIgnore`.
std.foldl(function(filteredObject, currentField)
// If current field is in `fieldsToIgnore`, return the filtered object as is.
// Otherwise, add the current field to the filtered object.
(
if std.member(fieldsToIgnore, currentField) then
filteredObject
else
filteredObject + { [currentField]: inputObject[currentField] }
),
// Starting with an empty object and iterating over each field in the input object.
std.objectFields(inputObject), {}),
} Then you can use it like: local filter = import 'filter.libsonnet';
local fieldsToIgnore = [
'ignore1',
'ignore2',
'ignore3',
];
local objectToFilter = {
'field1': 'value1',
'field2': 'value2',
'ignore1': 'value3',
// ...
};
// Filter object
filter.filterObjectFields(objectToFilter, fieldsToIgnore) Works well for my use case but might not be the most optimal solution out there. Maybe that helps someone. |
If someone wants to add the ability to do :: in an object comprehension
then please send a PR (go-jsonnet only is fine)
Ditto for +: and +:: (neither of which we support)
…On Thu, 1 Jun 2023 at 10:25, Icereed ***@***.***> wrote:
Hey there,
I went with this approach which allows multiple fields to be ignored.
In my filter.libsonnet file I got this:
{
// Function to filter an object by excluding specified fields.
// Parameters:
// - inputObject: The object to be filtered.
// - fieldsToIgnore: List of fields to be ignored from the input object.
filterObjectFields(inputObject, fieldsToIgnore)::
// Iterating over the fields in the input object and creating a new object
// without the fields specified in `fieldsToIgnore`.
std.foldl(function(filteredObject, currentField)
// If current field is in `fieldsToIgnore`, return the filtered object as is.
// Otherwise, add the current field to the filtered object.
(
if std.member(fieldsToIgnore, currentField) then
filteredObject
else
filteredObject + { [currentField]: inputObject[currentField] }
),
// Starting with an empty object and iterating over each field in the input object.
std.objectFields(inputObject), {}),
}
Then you can use it like:
local filter = import 'filter.libsonnet';
local fieldsToIgnore = [
'ignore1',
'ignore2',
'ignore3',
];
local objectToFilter = {
'field1': 'value1',
'field2': 'value2',
'ignore1': 'value3',
// ...
};
// Filter object
filter.filterObjectFields(objectToFilter, fieldsToIgnore)
Works well for my use case but might not be the most optimal solution out
there. Maybe that helps someone.
—
Reply to this email directly, view it on GitHub
<#312 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABJBXTOBJVRZVUMZ47E4ZLXJBNXDANCNFSM4DM6NSPA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
(in response to #312 (comment)) as a simpler workaround to manually rolling recursive functions, fold can be used: local hide(obj, field=null, pred=function(name) (name == field), map=function(value) value) =
std.foldl(
function(acc, f)
if pred(f.key) then
acc { [f.key]:: map(f.value) }
else
acc { [f.key]: f.value },
std.objectKeysValues(obj),
{}
); (code with tests https://gist.github.com/mkmik/ba6110b5fa23352f9c9304a6aa51e614) of course, if one only wants to hide a field with a given name, that's just local hide(obj, field) = obj { [field]:: std.get(obj, field) }; the object-comprehension is needed if you want to apply some predicates and/or map the values. (unrelated note: I was pleasantly surprised when I learned that you can have a default argument of a function depend on another argument of the function, e.g. above in the |
I didn't read through all of this issue, but does #1070 address this? Should this issue be closed? |
I don't think we want to implement anything more, so yeah, I'm going to close this. |
I haven't found examples nor a way to easily remove a field from an object.
I can eventually iterate over all key and skip the one I want to remove to build a new object with dict comprehension, but the object would lost hidden fields.
The text was updated successfully, but these errors were encountered: