# Functions for structures ## TryMember {#trymember} Trying to get a field from the structure. If it's not found among the fields or null in the structure value, use the default value. Arguments: 1. Structure. 2. Field name. 3. Default value. ```yql $struct = <|a:1|>; SELECT TryMember( $struct, "a", 123 ) AS a, -- 1 TryMember( $struct, "b", 123 ) AS b; -- 123 ``` ## ExpandStruct {#expandstruct} Adding one or more new fields to the structure. If the field set contains duplicate values, an error is returned. Arguments: * The first argument passes the source structure to be expanded. * All the other arguments must be named, each argument adds a new field and the argument's name is used as the field's name (as in [AsStruct](basic.md#asstruct)). ### Examples ```yql $struct = <|a:1|>; SELECT ExpandStruct( $struct, 2 AS b, "3" AS c ) AS abc; ``` ## AddMember {#addmember} Adding one new field to the structure. If you need to add multiple fields, better use [ExpandStruct](#expandstruct). If the field set contains duplicate values, an error is returned. Arguments: 1. Source structure. 2. Name of the new field. 3. Value of the new field. ### Examples ```yql $struct = <|a:1|>; SELECT AddMember( $struct, "b", 2 ) AS ab; ``` ## RemoveMember {#removemember} Removing a field from the structure. If the entered field hasn't existed, an error is returned. Arguments: 1. Source structure. 2. Field name. ### Examples ```yql $struct = <|a:1, b:2|>; SELECT RemoveMember( $struct, "b" ) AS a; ``` ## ForceRemoveMember {#forceremovemember} Removing a field from the structure. If the entered field hasn't existed, unlike [RemoveMember](#removemember), the error is not returned. Arguments: 1. Source structure. 2. Field name. ### Examples ```yql $struct = <|a:1, b:2|>; SELECT ForceRemoveMember( $struct, "c" ) AS ab; ``` ## ChooseMembers {#choosemembers} Selecting fields with specified names from the structure. If any of the fields haven't existed, an error is returned. Arguments: 1. Source structure. 2. List of field names. ### Examples ```yql $struct = <|a:1, b:2, c:3|>; SELECT ChooseMembers( $struct, ["a", "b"] ) AS ab; ``` ## RemoveMembers {#removemembers} Excluding fields with specified names from the structure. If any of the fields haven't existed, an error is returned. Arguments: 1. Source structure. 2. List of field names. ### Examples ```yql $struct = <|a:1, b:2, c:3|>; SELECT RemoveMembers( $struct, ["a", "b"] ) AS c; ``` ## ForceRemoveMembers {#forceremovemembers} Excluding fields with specified names from the structure. If any of the fields haven't existed, it is ignored. Arguments: 1. Source structure. 2. List of field names. ### Examples ```yql $struct = <|a:1, b:2, c:3|>; SELECT ForceRemoveMembers( $struct, ["a", "b", "z"] ) AS c; ``` ## CombineMembers {#combinemembers} Combining the fields from multiple structures into a new structure. If the resulting field set contains duplicate values, an error is returned. Arguments: two or more structures. ### Examples ```yql $struct1 = <|a:1, b:2|>; $struct2 = <|c:3|>; SELECT CombineMembers( $struct1, $struct2 ) AS abc; ``` ## FlattenMembers {#flattenmembers} Combining the fields from multiple new structures into another new structure with prefix support. If the resulting field set contains duplicate values, an error is returned. Arguments: two or more tuples of two items: prefix and structure. ### Examples ```yql $struct1 = <|a:1, b:2|>; $struct2 = <|c:3|>; SELECT FlattenMembers( AsTuple("foo", $struct1), -- fooa, foob AsTuple("bar", $struct2) -- barc ) AS abc; ``` ## StructMembers {#structmembers} Returns an unordered list of field names (possibly removing one Optional level) for a single argument that is a structure. For the `NULL` argument, an empty list of strings is returned. Argument: structure ### Examples ```yql $struct = <|a:1, b:2|>; SELECT StructMembers($struct); -- ['a', 'b'] ``` ## RenameMembers {#renamemembers} Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, an error is returned. For an Optional structure or `NULL`, the result has the same type. Arguments: 1. Source structure. 2. A tuple of field names: the original name, the new name. ### Examples ```yql $struct = <|a:1, b:2|>; SELECT RenameMembers($struct, [('a', 'c'), ('a', 'e')]); -- (b:2, c:1, e:1) ``` ## ForceRenameMembers {#forecerenamemembers} Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, the name is ignored. For an Optional structure or `NULL`, the result has the same type. Arguments: 1. Source structure. 2. A tuple of field names: the original name, the new name. ### Examples ```yql $struct = <|a:1, b:2|>; SELECT ForceRenameMembers($struct, [('a', 'c'), ('d', 'e')]); -- (b:2, c:1) ``` ## GatherMembers {#gathermembers} Returns an unordered list of tuples including the field name and value. For the `NULL` argument, `EmptyList` is returned. It can be used only in the cases when the types of items in the structure are the same or compatible. Returns an optional list for an optional structure. Argument: structure ### Examples ```yql $struct = <|a:1, b:2|>; SELECT GatherMembers($struct); -- [('a', 1), ('b', 2)] ``` ## SpreadMembers {#spreadmembers} Creates a structure with a specified list of fields and applies a specified list of edits to it in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is Optional or `NULL`, the result has the same type. If the list of edits includes a field that is not in the list of expected fields, an error is returned. Arguments: 1. List of tuples: field name, field value. 2. A list of all possible field names in the structure. ### Examples ```yql SELECT SpreadMembers([('a',1),('a',2)],['a','b']); -- (a: 2, b: null) ``` ## ForceSpreadMembers {#forcespreadmembers} Creates a structure with a specified list of fields and applies to it the specified list of updates in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is optional or equal to `NULL`, the result has the same type. If the list of updates includes a field that is not in the list of expected fields, this edit is ignored. Arguments: 1. List of tuples: field name, field value. 2. A list of all possible field names in the structure. ### Examples ```yql SELECT ForceSpreadMembers([('a',1),('a',2),('c',100)],['a','b']); -- (a: 2, b: null) ``` ## StructUnion, StructIntersection, StructDifference, StructSymmetricDifference Combine two structures using one of the four methods (using the provided lambda to merge fields with the same name): * `StructUnion` adds all fields of both of the structures to the result. * `StructIntersection` adds only the fields which are present in both of the structures. * `StructDifference` adds only the fields of `left`, which are absent in `right`. * `StructSymmetricDifference` adds all fields that are present in exactly one of the structures. ### Signatures ```yql StructUnion(left:Struct<...>, right:Struct<...>[, mergeLambda:(name:String, l:T1?, r:T2?)->T])->Struct<...> StructIntersection(left:Struct<...>, right:Struct<...>[, mergeLambda:(name:String, l:T1?, r:T2?)->T])->Struct<...> StructDifference(left:Struct<...>, right:Struct<...>)->Struct<...> StructSymmetricDifference(left:Struct<...>, right:Struct<...>)->Struct<...> ``` Arguments: 1. `left` - first structure. 2. `right` - second structure. 3. `mergeLambda` - _(optional)_ function to merge fields with the same name (arguments: field name, `Optional` field value of the first struct, `Optional` field value of the second struct - arguments are `Nothing` in case of absence of the corresponding struct field). By default, if present, the first structure's field value is used; otherwise, the second one's value is used. ### Examples ```yql $merge = ($name, $l, $r) -> { return ($l ?? 0) + ($r ?? 0); }; $left = <|a: 1, b: 2, c: 3|>; $right = <|c: 1, d: 2, e: 3|>; SELECT StructUnion($left, $right), -- <|a: 1, b: 2, c: 3, d: 2, e: 3|> StructUnion($left, $right, $merge), -- <|a: 1, b: 2, c: 4, d: 2, e: 3|> StructIntersection($left, $right, $merge), -- <|c: 4|> StructDifference($left, $right), -- <|a: 1, b: 1|> StructSymmetricDifference($left, $right) -- <|a: 1, b: 2, d: 2, e: 3|> ; ```