Skip to content

DeepDataUpdate

youyihj edited this page Nov 16, 2023 · 3 revisions

IData Deep Update

@since 1.14.0

IData#update updates values of an IData, but origin elements are overwrote. This means

import crafttweaker.data.IData;

val a as IData = {
    foo: {
        bar: 0
    },
    baz: 5
};
val b as IData = {
    foo: {
        abc: 1
    }
};
print(a.update(b));

It prints {foo: {abc: 1}, baz: 5}. The previous element bar: 0 in sub-data foo is overwrote. ZenUtils adds IData#deepUpdate method, which also updates sub-data.

Same as IData#update, the method doesn't modify the original data, it returns a new data with updated values.

Method

IData.deepUpdate(IData toUpdate, @Optional IData updateOperation)

Update Operation

Update Operation describes how to update the data. You can import mods.zenutils.DataUpdateOperation package to access available operations.

  • OVERWRITE The old data is overwritten by the new data, like IData#update. It is the default behavior.

  • APPEND For list and array, the new data are put after the old data. For map, the new data will put to the map, keeping old elements that not updated. (map is unordered)

  • MERGE For list and array, the new data that the previous list doesn't contain are put after the old data. For map, it is equivalent to APPEND.

  • REMOVE Removes specific elements of list, array and map. If the data to be updated is empty, the original elements will be cleared.

  • BUMP Or-ing the four kinds of previous operations to mark the data list to be updated as a single data, rather a list containing multiple data.

Example

import crafttweaker.data.IData;
import mods.zenutils.DataUpdateOperation.OVERWRITE;
import mods.zenutils.DataUpdateOperation.APPEND;
import mods.zenutils.DataUpdateOperation.MERGE;
import mods.zenutils.DataUpdateOperation.REMOVE;
import mods.zenutils.DataUpdateOperation.BUMP;

val overwriteTestA as IData = {foo: {bar: 0}, baz: 5};
val overwriteTestB as IData = {foo: {abc: 1}};
// prints {foo: {abc: 1}}
// the whole data is overwritten by overwriteTestB
print(overwriteTestA.deepUpdate(overwriteTestB, OVERWRITE));

val appendTestA as IData = {pos: [{x: 5, y: 6, z: 7}]};
val appendTestB as IData = {pos: [{z: 8}, {x: 10, y: 11, z: 12}]};
// prints {pos: [{x: 5, y: 6, z: 7}, {z: 8}, {x: 10, y: 11, z: 12}]}
// adds a new element the list at key pos
print(appendTestA.deepUpdate(appendTestB, MERGE));

val listTestA as IData = ["a", "b", "c", "d"];
val listTestB as IData = ["d", "e", "f", "g"];

// prints ["d", "e", "f", "g"]
// only keep the updated values
print(listTestA.deepUpdate(listTestB, OVERWRITE));

// prints ["a", "b", "c", "d", "d", "e", "f", "g"]
// connects the two lists together
print(listTestA.deepUpdate(listTestB, APPEND));

// prints ["a", "b", "c", "d", "e", "f", "g"]
// duplicate element d is not added
print(listTestA.deepUpdate(listTestB, MERGE));

// prints ["a", "b", "c"]
// element d is removed
print(listTestA.deepUpdate(listTestB, REMOVE));

// prints ["a", "b", "c", "d", ["d", "e", "f", "g"]]
// adds ["d", "e", "f", "g"] as *one* element to the list
// Converting the output of this example to Minecraft NBT will result in an error
// But it is useful to handle data form like [[xxx, xxx], [xxx, xxx]]
print(listTestA.deepUpdate(listTestB, BUMP | APPEND));

// prints {baz: 5, foo: {abc: 1}}
// updates value at key foo, overwrite operation
val treeOverwriteTestA as IData = {foo: {bar: 0}, baz: 5};
val treeOverwriteTestB as IData = {foo: {abc: 1}};
print(treeOverwriteTestA.deepUpdate(treeOverwriteTestB, {foo: OVERWRITE}));

val listMapTestA as IData = [{x: 1, y: 2, z: 3}, {x: 4, y: 5, z: 6}];
val listMapTestB as IData = [{x: 7, y: 8, z: 9}];
// prints [{x: 1, y: 2, z: 3}, {x: 4, y: 5, z: 6}, {x: 7, y: 8, z: 9}]
print(listMapTestA.deepUpdate(listMapTestB, APPEND));
// prints [{x: 7, y: 8, z: 9}, {x: 4, y: 5, z: 6}]
// updates the element at index 0
// {x: 1, y: 2, z: 3} -> {x: 7, y: 8, z: 9}
print(listMapTestA.deepUpdate(listMapTestB, [APPEND]));

val nestedListOperatorTestA as IData = [[1, 2], [3, 4], [5, 6]];
val nestedListOperatorTestB as IData = [[3, 4], [4, 5], [5, 7]];
// prints [[3, 4], [3, 4, 5], [5, 6, 7]]
// index 0: OVERWRITE operation
// index 1: MERGE operation
// index 2: not given, use the last given operation MERGE
print(nestedListOperatorTestA.deepUpdate(nestedListOperatorTestB, [OVERWRITE, MERGE]));

val nestedListMapTestA as IData = {others: {}};
val nestedListMapTestB as IData = {key: [1, 2]};
val nestedListMapTestC as IData = {key: [3, 4]};
// prints {others: {}, key: [1, 2, 3, 4]}
print(nestedListMapTestA.deepUpdate(nestedListMapTestB, {key: APPEND})
    .deepUpdate(nestedListMapTestC, {key: APPEND})
);
// prints {others: {}, key: [[1, 2], [3, 4]]}
print(nestedListMapTestA.deepUpdate(nestedListMapTestB, {key: BUMP | APPEND})
    .deepUpdate(nestedListMapTestC, {key: BUMP | APPEND})
);
Clone this wiki locally