Zulhilmi Zainudin
Zulhilmi Zainudin

Reputation: 9345

How to access other object sibling's value?

I'm just wondering if it's possible to refer to self (object) value inside the object sibling like below?

[
  {
    "name": "Zulh",
    "name_uppercase": uppercase(self.name) // expects ZULH
  },
  {
    "name": "John",
    "name_uppercase": uppercase(self.name) // expects JOHN
  }
]

Note:

Code for uppercase is omitted for brevity. In my real code, it's doing synchronous complex stuff and is not actually simple string case manipulation like that.

Upvotes: 3

Views: 2242

Answers (7)

Nimeshka Srimal
Nimeshka Srimal

Reputation: 8930

How about using a getter method?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

The get syntax binds an object property to a function that will be called when that property is looked up.

foo = [
  {
    "name": "Zulh",
    get name_uppercase () {
        return (this.name).toUpperCase();
    }
  },
  {
    "name": "John",
    get name_uppercase () {
        return (this.name).toUpperCase();
    }
  }
]

console.log(foo[1].name_uppercase); //returns JOHN

Hope it helps :)

Upvotes: 0

Ivan
Ivan

Reputation: 40648

Using a GETTER

If you want to keep it dynamic and make it work even if you change the name property, you can use a GETTER to do this kind of thing:

const names = [
  {
    "name": "John",
    get name_uppercase() {
      return this.name.toUpperCase();
    }
  }
]

console.log(names[0].name_uppercase)


GETTER for multiple objects

You don't have to write this for every property manually! Use .forEach:

const names = [
  {
    "name": "John"    
  },
  {
    "name": "Mike"
  }
]

names.forEach(object => {

  Object.defineProperty(object, 'nameUppercase', {
  
    get: function() { return this.name.toUpperCase() }
  
  });
  
});



console.log(names[0].nameUppercase)
console.log(names[1].nameUppercase)


Using a class and a GETTER

Or as @Rajesh pointed out you can use a class instead:

class Person {

  constructor(name) {
  
    this.name = name;
    
  }

  get nameUpperCase() {
  
    return this.name.toUpperCase();
  
  }

}

const names = [ new Person("John"), new Person("Mike")];

console.log(names[0].nameUpperCase);
console.log(names[1].nameUpperCase);

Upvotes: 4

Mihai T
Mihai T

Reputation: 17687

I would suggest 2 approaches:

  1. If you DO NOT want to change your initial array ( which is recommended ), use map which returns a new array with changed values ( calls a function for every array item ) .

See below

let arr = [
  {
    "name": "Zulh",
  },
  {
    "name": "John",
  }
];
const newArr = arr.map((x)=>{
	x.name_uppercase = (x.name).toUpperCase()
    return x
})
console.log(newArr)

  1. If you don't mind changing your initial array, you can use forEach. Keep in mind that unlike map, forEach changes your array and so it doesn't return anything.

let arr = [
  {
    "name": "Zulh",
  },
  {
    "name": "John",
  }
];
arr.forEach((x)=>{
  x.name_uppercase = (x.name).toUpperCase()
})
console.log(arr)

So it all depends if you want to change your current array or not

Upvotes: 0

Shilly
Shilly

Reputation: 8589

You can't do this with the object literal syntax, since it's 'this' property will not be set at that time. For example, if you'd run your code in the browser, 'this' would refer to the window object.

So you'll either have to use one of the other answers or go for a 'class':

var uppercase = function( str ) {
  return str.toUpperCase();
};
var Person = function( name ) {
  this.name = name;
  this.name_uppercase = uppercase( this.name );
};
var persons = [
  new Person( 'zuhi' ),
  new Person( 'john' )
];
console.log( persons );

Same can be written in ES6 class syntax.

Upvotes: 0

Icepickle
Icepickle

Reputation: 12796

Why not create a function that transforms your incoming array? A way to do it could be like this:

const value = [
  {
    "name": "Zulh"
  },
  {
    "name": "John"
  }
];

const transform = ( array, propertyToUpdate, propertyToCreate, transformation ) => {
  return array.map( item => ({ ...item, [propertyToCreate]: transformation( item[propertyToUpdate] ) }) );
};

console.log( transform( value, 'name', 'name_uppercase', ( item ) => item.toUpperCase() ) );

Upvotes: 0

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28455

You can use Array.forEach and update the objects in Array

var data = [{"name": "Zulh"},{"name": "John"}];
data.forEach(o=> o.upper_case = o.name.toUpperCase());
console.log(data);

Upvotes: 0

Muhammad Usman
Muhammad Usman

Reputation: 10148

You can't reference an object during initialization when using object literal syntax.. Inshort, that's not possible what you expect above

Well, you can use map and add additional/modified properties to you object like

data.map(o=> ({name: o.name, upper_case : o.name.toUpperCase()}))

var data = [
  {
    "name": "Zulh" 
    
  },
  {
    "name": "John" 
   
  }
];

var x = data.map(o=> ({name: o.name, upper_case : o.name.toUpperCase()}))

console.log(x)

Upvotes: 3

Related Questions