or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdcore.mdindex.mdnested-operations.mdobject-operations.md

nested-operations.mddocs/

0

# Nested Operations

1

2

Methods for working with nested data structures using path-based access patterns. These operations work on both objects and arrays using array paths to specify nested locations.

3

4

## Capabilities

5

6

### setIn

7

8

Sets a nested property using a path array, creating intermediate objects/arrays as needed.

9

10

```javascript { .api }

11

/**

12

* Set nested property using path array

13

* @param {Object|Array} obj - Target object or array

14

* @param {Array} path - Array of keys/indices representing the path to the nested property

15

* @param {*} value - Value to set at the nested location

16

* @param {Object} [config] - Configuration options

17

* @param {boolean} [config.deep] - Deep merge if setting an object value

18

* @returns {Object|Array} New immutable structure with nested property set

19

*/

20

function setIn(obj, path, value, config);

21

```

22

23

**Usage Examples:**

24

25

```javascript

26

const Immutable = require("seamless-immutable");

27

28

// Setting in nested objects

29

const obj = Immutable({type: {main: "parrot", sub: "Norwegian Blue"}, status: "alive"});

30

const updated = obj.setIn(["type", "sub"], "Norwegian Ridgeback");

31

// Result: {type: {main: "parrot", sub: "Norwegian Ridgeback"}, status: "alive"}

32

33

// Setting in nested arrays

34

const arr = Immutable([[1, 2], [3, 4]]);

35

const updatedArr = arr.setIn([1, 0], 99);

36

// Result: [[1, 2], [99, 4]]

37

38

// Creating intermediate structures

39

const empty = Immutable({});

40

const nested = empty.setIn(["user", "profile", "name"], "Alice");

41

// Result: {user: {profile: {name: "Alice"}}}

42

43

// Mixed object/array paths

44

const complex = Immutable({users: [{name: "Alice"}, {name: "Bob"}]});

45

const updatedComplex = complex.setIn(["users", 0, "age"], 30);

46

// Result: {users: [{name: "Alice", age: 30}, {name: "Bob"}]}

47

48

// Deep merge when setting objects

49

const deepObj = Immutable({user: {name: "Alice", settings: {theme: "dark"}}});

50

const merged = deepObj.setIn(["user"], {age: 30}, {deep: true});

51

// Result: {user: {name: "Alice", age: 30, settings: {theme: "dark"}}}

52

```

53

54

### getIn

55

56

Gets a nested property value using a path array, with optional default value.

57

58

```javascript { .api }

59

/**

60

* Get nested property using path array

61

* @param {Object|Array} obj - Target object or array

62

* @param {Array} path - Array of keys/indices representing the path to the nested property

63

* @param {*} [defaultValue] - Default value returned if path is not found

64

* @returns {*} Value at the specified path, or defaultValue if not found

65

*/

66

function getIn(obj, path, defaultValue);

67

```

68

69

**Usage Examples:**

70

71

```javascript

72

const Immutable = require("seamless-immutable");

73

74

const obj = Immutable({

75

type: {main: "parrot", subtype: "Norwegian Blue"},

76

status: "alive",

77

users: [{name: "Alice", age: 30}, {name: "Bob", age: 25}]

78

});

79

80

// Get nested object property

81

const subtype = obj.getIn(["type", "subtype"]);

82

// Result: "Norwegian Blue"

83

84

// Get from nested array

85

const firstUserName = obj.getIn(["users", 0, "name"]);

86

// Result: "Alice"

87

88

// Path not found - returns undefined

89

const missing = obj.getIn(["type", "missing"]);

90

// Result: undefined

91

92

// Path not found with default value

93

const withDefault = obj.getIn(["type", "class"], "Aves");

94

// Result: "Aves"

95

96

// Deeply nested path

97

const deepNested = Immutable({a: {b: {c: {d: "found"}}}});

98

const value = deepNested.getIn(["a", "b", "c", "d"]);

99

// Result: "found"

100

101

// Array indices in path

102

const matrix = Immutable([[1, 2, 3], [4, 5, 6]]);

103

const element = matrix.getIn([1, 2]);

104

// Result: 6

105

```

106

107

### updateIn

108

109

Updates a nested property using an updater function and path array.

110

111

```javascript { .api }

112

/**

113

* Update nested property using updater function and path array

114

* @param {Object|Array} obj - Target object or array

115

* @param {Array} path - Array of keys/indices representing the path to the nested property

116

* @param {Function} updater - Function that receives current value and returns new value

117

* @param {...*} [args] - Additional arguments passed to the updater function

118

* @returns {Object|Array} New immutable structure with updated nested property

119

*/

120

function updateIn(obj, path, updater, ...args);

121

```

122

123

**Usage Examples:**

124

125

```javascript

126

const Immutable = require("seamless-immutable");

127

128

// Simple numeric update

129

function add(x, y) { return x + y; }

130

const obj = Immutable({foo: {bar: 1}});

131

const incremented = obj.updateIn(["foo", "bar"], add, 10);

132

// Result: {foo: {bar: 11}}

133

134

// String manipulation

135

const user = Immutable({profile: {name: "alice"}});

136

const capitalized = user.updateIn(["profile", "name"], name => name.toUpperCase());

137

// Result: {profile: {name: "ALICE"}}

138

139

// Array manipulation

140

const data = Immutable({items: {list: [1, 2, 3]}});

141

const withNewItem = data.updateIn(["items", "list"], list => list.concat(4));

142

// Result: {items: {list: [1, 2, 3, 4]}}

143

144

// Complex nested structure

145

const state = Immutable({

146

users: [

147

{id: 1, name: "Alice", scores: [10, 20]},

148

{id: 2, name: "Bob", scores: [15, 25]}

149

]

150

});

151

152

// Update nested array element

153

const updatedScores = state.updateIn(["users", 0, "scores"], scores =>

154

scores.map(score => score * 2)

155

);

156

// Result: users[0].scores becomes [20, 40]

157

158

// Update with multiple arguments

159

function multiply(current, factor, bonus) {

160

return current * factor + bonus;

161

}

162

const calculated = obj.updateIn(["foo", "bar"], multiply, 3, 5);

163

// Result: {foo: {bar: 8}} (1 * 3 + 5)

164

```

165

166

### update (Single-level)

167

168

Updates a property at the current level using an updater function.

169

170

```javascript { .api }

171

/**

172

* Update a property using an updater function

173

* @param {Object|Array} obj - Target object or array

174

* @param {string|number} property - Property key or array index to update

175

* @param {Function} updater - Function that receives current value and returns new value

176

* @param {...*} [args] - Additional arguments passed to the updater function

177

* @returns {Object|Array} New immutable structure with updated property

178

*/

179

function update(obj, property, updater, ...args);

180

```

181

182

**Usage Examples:**

183

184

```javascript

185

const Immutable = require("seamless-immutable");

186

187

// Object property update

188

function inc(x) { return x + 1; }

189

const obj = Immutable({foo: 1, bar: 2});

190

const incremented = obj.update("foo", inc);

191

// Result: {foo: 2, bar: 2}

192

193

// Array element update

194

const arr = Immutable([10, 20, 30]);

195

const doubled = arr.update(1, x => x * 2);

196

// Result: [10, 40, 30]

197

198

// Update with additional arguments

199

function add(current, amount) { return current + amount; }

200

const added = obj.update("foo", add, 5);

201

// Result: {foo: 6, bar: 2}

202

203

// Conditional updates

204

const conditionalUpdate = obj.update("foo", (current, threshold) =>

205

current > threshold ? current * 2 : current

206

, 0.5);

207

```

208

209

## Path Resolution

210

211

### Automatic Structure Creation

212

213

When using `setIn`, intermediate structures are automatically created based on the next key in the path:

214

215

```javascript

216

const Immutable = require("seamless-immutable");

217

218

const empty = Immutable({});

219

220

// Creates nested objects

221

const result1 = empty.setIn(["a", "b", "c"], "value");

222

// Result: {a: {b: {c: "value"}}}

223

224

// Creates array when next key is numeric

225

const result2 = empty.setIn(["users", 0, "name"], "Alice");

226

// Result: {users: [{name: "Alice"}]}

227

228

// Mixed creation

229

const result3 = empty.setIn(["data", 0, "items", "first"], "value");

230

// Result: {data: [{items: {first: "value"}}]}

231

```

232

233

### Path Validation

234

235

Paths must be arrays with at least one element:

236

237

```javascript

238

const obj = Immutable({a: 1});

239

240

// Valid paths

241

obj.setIn(["a"], 2); // ✓

242

obj.setIn(["b", "c"], 3); // ✓

243

obj.setIn([0, "name"], "test"); // ✓

244

245

// Invalid paths - throw TypeError

246

obj.setIn([], "value"); // ✗ Empty path

247

obj.setIn("a", "value"); // ✗ Not an array

248

obj.setIn(null, "value"); // ✗ Null path

249

```

250

251

### Working with Mixed Structures

252

253

Nested operations handle complex data structures with mixed objects and arrays:

254

255

```javascript

256

const Immutable = require("seamless-immutable");

257

258

const complexData = Immutable({

259

users: [

260

{

261

id: 1,

262

profile: {

263

name: "Alice",

264

addresses: [

265

{type: "home", city: "NYC"},

266

{type: "work", city: "SF"}

267

]

268

}

269

}

270

],

271

settings: {

272

theme: "dark",

273

features: ["feature1", "feature2"]

274

}

275

});

276

277

// Deep nested update

278

const updated = complexData.updateIn(

279

["users", 0, "profile", "addresses", 0, "city"],

280

city => city.toUpperCase()

281

);

282

283

// Get deep nested value

284

const workCity = complexData.getIn(["users", 0, "profile", "addresses", 1, "city"]);

285

286

// Set deep nested value

287

const withNewFeature = complexData.setIn(

288

["settings", "features", 2],

289

"feature3"

290

);

291

```

292

293

## Instance vs Static Methods

294

295

All nested operation methods are available in both instance and static forms:

296

297

```javascript

298

const Immutable = require("seamless-immutable");

299

const obj = Immutable({user: {name: "Alice"}});

300

301

// Instance methods (default API)

302

const set1 = obj.setIn(["user", "age"], 30);

303

const get1 = obj.getIn(["user", "name"]);

304

const updated1 = obj.updateIn(["user", "name"], name => name.toUpperCase());

305

306

// Static methods (static API)

307

const ImmutableS = require("seamless-immutable").static;

308

const set2 = ImmutableS.setIn(obj, ["user", "age"], 30);

309

const get2 = ImmutableS.getIn(obj, ["user", "name"]);

310

const updated2 = ImmutableS.updateIn(obj, ["user", "name"], name => name.toUpperCase());

311

```

312

313

The static API is recommended when you want to avoid method name pollution or work with a consistent functional programming style.