or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

function-functions.mdindex.mdlist-functions.mdmath-logic.mdobject-functions.mdstring-type.md

object-functions.mddocs/

0

# Object Functions

1

2

Ramda provides 57 comprehensive functions for working with objects and their properties. These functions enable immutable object manipulation, property access, and complex object transformations while maintaining functional programming principles.

3

4

## Property Access

5

6

### prop

7

Get a property value from an object.

8

9

```javascript { .api }

10

/**

11

* @param {String|Number} key - Property key to access

12

* @param {Object} obj - Object to read from

13

* @returns {*} Property value or undefined

14

*/

15

R.prop(key, obj)

16

17

const user = { name: 'John', age: 30, active: true };

18

19

R.prop('name', user); // => 'John'

20

R.prop('age', user); // => 30

21

R.prop('missing', user); // => undefined

22

23

// Curried usage for data extraction

24

const getName = R.prop('name');

25

const users = [{name: 'Alice'}, {name: 'Bob'}];

26

R.map(getName, users); // => ['Alice', 'Bob']

27

```

28

29

### props

30

Get multiple property values as an array.

31

32

```javascript { .api }

33

/**

34

* @param {Array} keys - Array of property keys

35

* @param {Object} obj - Object to read from

36

* @returns {Array} Array of property values

37

*/

38

R.props(keys, obj)

39

40

const user = { name: 'John', age: 30, city: 'NYC' };

41

42

R.props(['name', 'age'], user); // => ['John', 30]

43

R.props(['city', 'name'], user); // => ['NYC', 'John']

44

R.props(['missing', 'name'], user); // => [undefined, 'John']

45

46

// Extract specific fields from objects

47

const extractInfo = R.props(['id', 'name', 'email']);

48

const users = [{id: 1, name: 'Alice', email: 'alice@example.com', extra: 'data'}];

49

R.map(extractInfo, users); // => [[1, 'Alice', 'alice@example.com']]

50

```

51

52

### path

53

Access nested properties safely.

54

55

```javascript { .api }

56

/**

57

* @param {Array} pathArray - Array of keys for nested access

58

* @param {Object} obj - Object to traverse

59

* @returns {*} Nested property value or undefined

60

*/

61

R.path(pathArray, obj)

62

63

const user = {

64

profile: {

65

personal: { name: 'John', age: 30 },

66

contact: { email: 'john@example.com' }

67

}

68

};

69

70

R.path(['profile', 'personal', 'name'], user); // => 'John'

71

R.path(['profile', 'contact', 'email'], user); // => 'john@example.com'

72

R.path(['profile', 'missing', 'field'], user); // => undefined

73

R.path(['a', 'b'], { a: { b: 2 } }); // => 2

74

75

// Safe access prevents errors

76

R.path(['deep', 'nested', 'prop'], {}); // => undefined (no error)

77

```

78

79

### pathOr

80

Access nested properties with default value.

81

82

```javascript { .api }

83

/**

84

* @param {*} defaultValue - Value to return if path doesn't exist

85

* @param {Array} pathArray - Array of keys for nested access

86

* @param {Object} obj - Object to traverse

87

* @returns {*} Nested property value or default

88

*/

89

R.pathOr(defaultValue, pathArray, obj)

90

91

const config = { api: { timeout: 5000 } };

92

93

R.pathOr(3000, ['api', 'timeout'], config); // => 5000

94

R.pathOr(3000, ['api', 'retries'], config); // => 3000 (default)

95

R.pathOr('Unknown', ['user', 'name'], {}); // => 'Unknown'

96

```

97

98

## Object Copying and Cloning

99

100

### clone

101

Create a deep copy of an object or array.

102

103

```javascript { .api }

104

/**

105

* @param {*} value - Value to clone (object, array, or primitive)

106

* @returns {*} Deep copy of the value

107

*/

108

R.clone(value)

109

110

const original = {

111

name: 'John',

112

scores: [85, 90, 78],

113

profile: { age: 30, active: true }

114

};

115

116

const copied = R.clone(original);

117

copied.scores.push(95); // Original scores unchanged

118

copied.profile.age = 31; // Original profile unchanged

119

120

// Safe for nested structures

121

const nestedArray = [[1, 2], [3, 4]];

122

const clonedArray = R.clone(nestedArray);

123

clonedArray[0].push(3); // Original array unchanged

124

125

// Handles various data types

126

R.clone([1, 2, 3]); // => [1, 2, 3] (new array)

127

R.clone({a: 1}); // => {a: 1} (new object)

128

R.clone('hello'); // => 'hello' (primitives return as-is)

129

```

130

131

## Property Modification

132

133

### assoc

134

Set a property (immutable).

135

136

```javascript { .api }

137

/**

138

* @param {String|Number} key - Property key to set

139

* @param {*} value - Value to assign

140

* @param {Object} obj - Object to modify

141

* @returns {Object} New object with property set

142

*/

143

R.assoc(key, value, obj)

144

145

const user = { name: 'John', age: 30 };

146

147

R.assoc('age', 31, user); // => { name: 'John', age: 31 }

148

R.assoc('city', 'NYC', user); // => { name: 'John', age: 30, city: 'NYC' }

149

150

// Original object unchanged

151

console.log(user); // => { name: 'John', age: 30 }

152

153

// Curried usage for object updates

154

const addTimestamp = R.assoc('timestamp', Date.now());

155

const withTimestamp = addTimestamp({ data: 'value' });

156

```

157

158

### assocPath

159

Set nested property (immutable).

160

161

```javascript { .api }

162

/**

163

* @param {Array} pathArray - Array of keys for nested access

164

* @param {*} value - Value to set at path

165

* @param {Object} obj - Object to modify

166

* @returns {Object} New object with nested property set

167

*/

168

R.assocPath(pathArray, value, obj)

169

170

const user = { profile: { name: 'John', settings: { theme: 'dark' } } };

171

172

R.assocPath(['profile', 'name'], 'Jane', user);

173

// => { profile: { name: 'Jane', settings: { theme: 'dark' } } }

174

175

R.assocPath(['profile', 'settings', 'theme'], 'light', user);

176

// => { profile: { name: 'John', settings: { theme: 'light' } } }

177

178

// Create missing intermediate objects

179

R.assocPath(['new', 'nested', 'prop'], 'value', {});

180

// => { new: { nested: { prop: 'value' } } }

181

```

182

183

### dissoc

184

Remove a property (immutable).

185

186

```javascript { .api }

187

/**

188

* @param {String} key - Property key to remove

189

* @param {Object} obj - Object to modify

190

* @returns {Object} New object without the property

191

*/

192

R.dissoc(key, obj)

193

194

const user = { name: 'John', age: 30, temp: 'remove-me' };

195

196

R.dissoc('temp', user); // => { name: 'John', age: 30 }

197

R.dissoc('missing', user); // => { name: 'John', age: 30, temp: 'remove-me' }

198

199

// Remove multiple properties

200

const removeFields = R.pipe(

201

R.dissoc('temp'),

202

R.dissoc('internal')

203

);

204

```

205

206

### dissocPath

207

Remove nested property (immutable).

208

209

```javascript { .api }

210

/**

211

* @param {Array} pathArray - Array of keys for nested access

212

* @param {Object} obj - Object to modify

213

* @returns {Object} New object without the nested property

214

*/

215

R.dissocPath(pathArray, obj)

216

217

const user = {

218

profile: {

219

name: 'John',

220

settings: { theme: 'dark', lang: 'en' }

221

}

222

};

223

224

R.dissocPath(['profile', 'settings', 'theme'], user);

225

// => { profile: { name: 'John', settings: { lang: 'en' } } }

226

```

227

228

## Object Transformation

229

230

### evolve

231

Transform object properties using functions.

232

233

```javascript { .api }

234

/**

235

* @param {Object} transformations - Object mapping keys to transformation functions

236

* @param {Object} obj - Object to transform

237

* @returns {Object} New object with properties transformed

238

*/

239

R.evolve(transformations, obj)

240

241

const user = { name: ' john ', age: '30', active: 'true' };

242

243

const transformations = {

244

name: R.pipe(R.trim, R.toUpper),

245

age: parseInt,

246

active: R.equals('true')

247

};

248

249

R.evolve(transformations, user);

250

// => { name: 'JOHN', age: 30, active: true }

251

252

// Nested transformations

253

const nestedTransform = {

254

profile: {

255

name: R.toUpper,

256

age: R.add(1)

257

}

258

};

259

260

R.evolve(nestedTransform, {

261

profile: { name: 'john', age: 30 },

262

other: 'unchanged'

263

});

264

// => { profile: { name: 'JOHN', age: 31 }, other: 'unchanged' }

265

```

266

267

### modify

268

Transform a specific property.

269

270

```javascript { .api }

271

/**

272

* @param {String|Number} key - Property key to modify

273

* @param {Function} fn - Transformation function

274

* @param {Object} obj - Object to modify

275

* @returns {Object} New object with property transformed

276

*/

277

R.modify(key, fn, obj)

278

279

const user = { name: 'john', age: 30, scores: [85, 90, 78] };

280

281

R.modify('name', R.toUpper, user); // => { name: 'JOHN', age: 30, scores: [85, 90, 78] }

282

R.modify('age', R.add(1), user); // => { name: 'john', age: 31, scores: [85, 90, 78] }

283

R.modify('scores', R.append(95), user); // => { name: 'john', age: 30, scores: [85, 90, 78, 95] }

284

```

285

286

### modifyPath

287

Transform a nested property.

288

289

```javascript { .api }

290

/**

291

* @param {Array} pathArray - Array of keys for nested access

292

* @param {Function} fn - Transformation function

293

* @param {Object} obj - Object to modify

294

* @returns {Object} New object with nested property transformed

295

*/

296

R.modifyPath(pathArray, fn, obj)

297

298

const state = {

299

user: {

300

profile: { name: 'john', visits: 5 }

301

}

302

};

303

304

R.modifyPath(['user', 'profile', 'name'], R.toUpper, state);

305

// => { user: { profile: { name: 'JOHN', visits: 5 } } }

306

307

R.modifyPath(['user', 'profile', 'visits'], R.inc, state);

308

// => { user: { profile: { name: 'john', visits: 6 } } }

309

```

310

311

## Object Merging

312

313

### merge

314

Shallow merge two objects.

315

316

```javascript { .api }

317

/**

318

* @param {Object} obj1 - First object

319

* @param {Object} obj2 - Second object (properties override obj1)

320

* @returns {Object} New merged object

321

*/

322

R.merge(obj1, obj2)

323

324

const defaults = { timeout: 5000, retries: 3 };

325

const config = { timeout: 8000, debug: true };

326

327

R.merge(defaults, config);

328

// => { timeout: 8000, retries: 3, debug: true }

329

330

// Curried usage for applying defaults

331

const withDefaults = R.merge({ theme: 'light', lang: 'en' });

332

withDefaults({ theme: 'dark' }); // => { theme: 'dark', lang: 'en' }

333

```

334

335

### mergeDeepLeft, mergeDeepRight

336

Deep merge objects with conflict resolution.

337

338

```javascript { .api }

339

const obj1 = {

340

a: 1,

341

nested: { x: 10, y: 20 }

342

};

343

344

const obj2 = {

345

b: 2,

346

nested: { x: 30, z: 40 }

347

};

348

349

// Left object takes precedence

350

R.mergeDeepLeft(obj1, obj2);

351

// => { a: 1, b: 2, nested: { x: 10, y: 20, z: 40 } }

352

353

// Right object takes precedence

354

R.mergeDeepRight(obj1, obj2);

355

// => { a: 1, b: 2, nested: { x: 30, y: 20, z: 40 } }

356

```

357

358

### mergeWith, mergeDeepWith

359

Merge objects with custom conflict resolution.

360

361

```javascript { .api }

362

/**

363

* @param {Function} conflictFn - Function to resolve conflicts (leftVal, rightVal) -> resolvedVal

364

* @param {Object} obj1 - First object

365

* @param {Object} obj2 - Second object

366

* @returns {Object} New merged object

367

*/

368

R.mergeWith(conflictFn, obj1, obj2)

369

370

const obj1 = { a: 1, b: [1, 2], c: 'hello' };

371

const obj2 = { a: 2, b: [3, 4], d: 'world' };

372

373

// Concatenate conflicting arrays, add numbers, take right for others

374

R.mergeWith(

375

(left, right) => {

376

if (Array.isArray(left)) return R.concat(left, right);

377

if (typeof left === 'number') return left + right;

378

return right;

379

},

380

obj1,

381

obj2

382

);

383

// => { a: 3, b: [1, 2, 3, 4], c: 'hello', d: 'world' }

384

```

385

386

## Object Introspection

387

388

### keys, values

389

Get object keys or values.

390

391

```javascript { .api }

392

const obj = { name: 'John', age: 30, active: true };

393

394

R.keys(obj); // => ['name', 'age', 'active']

395

R.values(obj); // => ['John', 30, true]

396

397

// keysIn and valuesIn include inherited properties

398

function Person(name) { this.name = name; }

399

Person.prototype.species = 'human';

400

const john = new Person('John');

401

402

R.keys(john); // => ['name']

403

R.keysIn(john); // => ['name', 'species']

404

```

405

406

### toPairs, toPairsIn

407

Convert object to key-value pairs.

408

409

```javascript { .api }

410

/**

411

* @param {Object} obj - Object to convert

412

* @returns {Array} Array of [key, value] pairs

413

*/

414

R.toPairs(obj)

415

416

const obj = { name: 'John', age: 30 };

417

418

R.toPairs(obj); // => [['name', 'John'], ['age', 30]]

419

420

// Convert back to object

421

R.fromPairs([['name', 'John'], ['age', 30]]); // => { name: 'John', age: 30 }

422

```

423

424

### has, hasIn, hasPath

425

Check property existence.

426

427

```javascript { .api }

428

const obj = { name: 'John', profile: { age: 30 } };

429

430

// Own properties only

431

R.has('name', obj); // => true

432

R.has('toString', obj); // => false

433

434

// Including inherited properties

435

R.hasIn('toString', obj); // => true

436

437

// Nested property existence

438

R.hasPath(['profile', 'age'], obj); // => true

439

R.hasPath(['profile', 'email'], obj); // => false

440

```

441

442

## Object Filtering and Selection

443

444

### pick, pickAll

445

Select specific properties.

446

447

```javascript { .api }

448

/**

449

* @param {Array} keys - Array of property keys to pick

450

* @param {Object} obj - Object to pick from

451

* @returns {Object} New object with only selected properties

452

*/

453

R.pick(keys, obj)

454

455

const user = { id: 1, name: 'John', email: 'john@example.com', password: 'secret' };

456

457

R.pick(['id', 'name'], user); // => { id: 1, name: 'John' }

458

R.pick(['name', 'missing'], user); // => { name: 'John' }

459

460

// pickAll includes undefined for missing keys

461

R.pickAll(['name', 'missing'], user); // => { name: 'John', missing: undefined }

462

463

// Create safe user objects

464

const safeUser = R.pick(['id', 'name', 'email']);

465

safeUser(user); // => { id: 1, name: 'John', email: 'john@example.com' }

466

```

467

468

### omit

469

Exclude specific properties.

470

471

```javascript { .api }

472

/**

473

* @param {Array} keys - Array of property keys to omit

474

* @param {Object} obj - Object to omit from

475

* @returns {Object} New object without specified properties

476

*/

477

R.omit(keys, obj)

478

479

const user = { id: 1, name: 'John', password: 'secret', temp: 'data' };

480

481

R.omit(['password', 'temp'], user); // => { id: 1, name: 'John' }

482

483

// Remove sensitive data

484

const sanitize = R.omit(['password', 'apiKey', 'secret']);

485

sanitize(user); // => { id: 1, name: 'John' }

486

```

487

488

### pickBy

489

Select properties by predicate.

490

491

```javascript { .api }

492

/**

493

* @param {Function} predicate - Function to test values (value, key) -> Boolean

494

* @param {Object} obj - Object to filter

495

* @returns {Object} New object with properties that satisfy predicate

496

*/

497

R.pickBy(predicate, obj)

498

499

const data = { a: 1, b: 'hello', c: null, d: 42, e: undefined };

500

501

R.pickBy(R.is(Number), data); // => { a: 1, d: 42 }

502

R.pickBy(R.complement(R.isNil), data); // => { a: 1, b: 'hello', d: 42 }

503

R.pickBy((val, key) => key.length > 1, { a: 1, bb: 2, ccc: 3 }); // => { bb: 2, ccc: 3 }

504

```

505

506

## Validation and Testing

507

508

### where, whereEq

509

Test object properties against specifications.

510

511

```javascript { .api }

512

/**

513

* @param {Object} spec - Object mapping keys to predicate functions

514

* @param {Object} testObj - Object to test

515

* @returns {Boolean} True if all predicates pass

516

*/

517

R.where(spec, testObj)

518

519

const spec = {

520

name: R.is(String),

521

age: R.both(R.is(Number), R.gte(R.__, 18)),

522

active: R.equals(true)

523

};

524

525

const user1 = { name: 'John', age: 25, active: true };

526

const user2 = { name: 'Jane', age: 16, active: true };

527

528

R.where(spec, user1); // => true

529

R.where(spec, user2); // => false (age < 18)

530

531

// whereEq tests for exact value equality

532

const activeUser = R.whereEq({ active: true, status: 'online' });

533

activeUser({ name: 'John', active: true, status: 'online' }); // => true

534

```

535

536

### eqProps

537

Compare property values between objects.

538

539

```javascript { .api }

540

/**

541

* @param {String} key - Property key to compare

542

* @param {Object} obj1 - First object

543

* @param {Object} obj2 - Second object

544

* @returns {Boolean} True if property values are equal

545

*/

546

R.eqProps(key, obj1, obj2)

547

548

const user1 = { name: 'John', age: 30 };

549

const user2 = { name: 'John', age: 25 };

550

551

R.eqProps('name', user1, user2); // => true

552

R.eqProps('age', user1, user2); // => false

553

```

554

555

## Advanced Object Operations

556

557

### lens, lensProp, lensPath

558

Create lenses for focused object updates.

559

560

```javascript { .api }

561

// Property lens

562

const nameLens = R.lensProp('name');

563

const user = { name: 'john', age: 30 };

564

565

R.view(nameLens, user); // => 'john' (get)

566

R.set(nameLens, 'Jane', user); // => { name: 'Jane', age: 30 } (set)

567

R.over(nameLens, R.toUpper, user); // => { name: 'JOHN', age: 30 } (transform)

568

569

// Path lens for nested access

570

const profileNameLens = R.lensPath(['profile', 'name']);

571

const state = { profile: { name: 'john', age: 30 } };

572

573

R.over(profileNameLens, R.toUpper, state);

574

// => { profile: { name: 'JOHN', age: 30 } }

575

```

576

577

### invert, invertObj

578

Swap keys and values.

579

580

```javascript { .api }

581

const roles = { admin: 'Alice', user: 'Bob', guest: 'Charlie' };

582

583

// Simple inversion (last value wins for duplicates)

584

R.invertObj(roles); // => { Alice: 'admin', Bob: 'user', Charlie: 'guest' }

585

586

// Handle duplicate values with arrays

587

R.invert({ a: 'x', b: 'y', c: 'x' }); // => { x: ['a', 'c'], y: ['b'] }

588

```

589

590

These object functions provide a comprehensive toolkit for immutable object manipulation, enabling sophisticated data transformations while maintaining the functional programming paradigm.