This question already has answers here:
How to list the properties of a JavaScript object?
(18 answers)
Closed 6 months ago.
I was wondering if there was any way in JavaScript to loop through an object like so.
for(var i in myObject) {
// ...
}
But get the name of each property like this.
for(var i in myObject) {
separateObj[myObject[i].name] = myObject[i];
}
I can't seem to find anything like it on Google. They say to pass the names of the variables with them but this is not an option for what I am trying to achieve.
Thanks for any help you can offer.
Use Object.keys():
var myObject = { a: 'c', b: 'a', c: 'b' };
var keyNames = Object.keys(myObject);
console.log(keyNames); // Outputs ["a","b","c"]
Object.keys() gives you an array of property names belonging to the input object.
i is the name.
for(var name in obj) {
alert(name);
var value = obj[name];
alert(value);
}
So you could do:
seperateObj[i] = myObject[i];
Disclaimer
I misunderstood the question to be: "Can I know the property name that an object was attached to", but chose to leave the answer since some people may end up here while searching for that.
No, an object could be attached to multiple properties, so it has no way of knowing its name.
var obj = {a:1};
var a = {x: obj, y: obj}
What would obj's name be?
Are you sure you don't just want the property name from the for loop?
for (var propName in obj) {
console.log("Iterating through prop with name", propName, " its value is ", obj[propName])
}
you can easily iterate in objects
eg: if the object is
var a = {a:'apple', b:'ball', c:'cat', d:'doll', e:'elephant'};
Object.keys(a).forEach(key => {
console.log(key) // returns the keys in an object
console.log(a[key]) // returns the appropriate value
})
for direct access a object property by position...
generally usefull for property [0]... so it holds info about the further...
or in node.js 'require.cache[0]' for the first loaded external module, etc. etc.
Object.keys( myObject )[ 0 ]
Object.keys( myObject )[ 1 ]
...
Object.keys( myObject )[ n ]
Other than "Object.keys( obj )", we have very simple "for...in" loop - which loops over enumerable property names of an object.
const obj = {"fName":"John","lName":"Doe"};
for (const key in obj) {
//This will give key
console.log(key);
//This will give value
console.log(obj[key]);
}
To get the property of the object or the "array key" or "array index" depending on what your native language is..... Use the Object.keys() method.
Important, this is only compatible with "Modern browsers":
So if your object is called, myObject...
var c = 0;
for(c in myObject) {
console.log(Object.keys(myObject[c]));
}
Walla! This will definitely work in the latest firefox and ie11 and chrome...
Here is some documentation at MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
IN ES5
E.G. you have this kind of object:
var ELEMENTS = {
STEP_ELEMENT: { ID: "0", imageName: "el_0.png" },
GREEN_ELEMENT: { ID: "1", imageName: "el_1.png" },
BLUE_ELEMENT: { ID: "2", imageName: "el_2.png" },
ORANGE_ELEMENT: { ID: "3", imageName: "el_3.png" },
PURPLE_ELEMENT: { ID: "4", imageName: "el_4.png" },
YELLOW_ELEMENT: { ID: "5", imageName: "el_5.png" }
};
And now if you want to have a function that if you pass '0' as a param - to get 'STEP_ELEMENT', if '2' to get 'BLUE_ELEMENT' and so for
function(elementId) {
var element = null;
Object.keys(ELEMENTS).forEach(function(key) {
if(ELEMENTS[key].ID === elementId.toString()){
element = key;
return;
}
});
return element;
}
This is probably not the best solution to the problem but its good to give you an idea how to do it.
Cheers.
As of 2018 , You can make use of Object.getOwnPropertyNames() as described in Developer Mozilla Documentation
const object1 = {
a: 1,
b: 2,
c: 3
};
console.log(Object.getOwnPropertyNames(object1));
// expected output: Array ["a", "b", "c"]
Using Object.keys() function for acquiring properties from an Object, and it can help search property by name, for example:
const Products = function(){
this.Product = "Product A";
this.Price = 9.99;
this.Quantity = 112;
};
// Simple find function case insensitive
let findPropByName = function(data, propertyName){
let props = [];
Object.keys(data).forEach(element => {
return props.push(element.toLowerCase());
});
console.log(props);
let i = props.indexOf(propertyName.toLowerCase());
if(i > -1){
return props[i];
}
return false;
};
// calling the function
let products = new Products();
console.log(findPropByName(products, 'quantity'));
When you do the for/in loop you put up first, i is the property name. So you have the property name, i, and access the value by doing myObject[i].
These solutions work too.
// Solution One
function removeProperty(obj, prop) {
var bool;
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
if (keys[i] === prop) {
delete obj[prop];
bool = true;
}
}
return Boolean(bool);
}
//Solution two
function removeProperty(obj, prop) {
var bool;
if (obj.hasOwnProperty(prop)) {
bool = true;
delete obj[prop];
}
return Boolean(bool);
}
Quick & dirty:
function getObjName(obj) {
return (wrap={obj}) && eval('for(p in obj){p}') && (wrap=null);
}
Related
This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 4 months ago.
I'm pulling items out of the DOM with jQuery and want to set a property on an object using the id of the DOM element.
Example
const obj = {}
jQuery(itemsFromDom).each(function() {
const element = jQuery(this)
const name = element.attr('id')
const value = element.attr('value')
// Here is the problem
obj.name = value
})
If itemsFromDom includes an element with an id of "myId", I want obj to have a property named "myId". The above gives me name.
How do I name a property of an object using a variable using JavaScript?
You can use this equivalent syntax:
obj[name] = value
Example:
let obj = {};
obj["the_key"] = "the_value";
or with ES6 features:
let key = "the_key";
let obj = {
[key]: "the_value",
};
in both examples, console.log(obj) will return: { the_key: 'the_value' }
With ECMAScript 2015 you can do it directly in object declaration using bracket notation:
var obj = {
[key]: value
}
Where key can be any sort of expression (e.g. a variable) returning a value:
var obj = {
['hello']: 'World',
[x + 2]: 42,
[someObject.getId()]: someVar
}
You can even make List of objects like this
var feeTypeList = [];
$('#feeTypeTable > tbody > tr').each(function (i, el) {
var feeType = {};
var $ID = $(this).find("input[id^=txtFeeType]").attr('id');
feeType["feeTypeID"] = $('#ddlTerm').val();
feeType["feeTypeName"] = $('#ddlProgram').val();
feeType["feeTypeDescription"] = $('#ddlBatch').val();
feeTypeList.push(feeType);
});
There are two different notations to access object properties
Dot notation: myObj.prop1
Bracket notation: myObj["prop1"]
Dot notation is fast and easy but you must use the actual property name explicitly. No substitution, variables, etc.
Bracket notation is open ended. It uses a string but you can produce the string using any legal js code. You may specify the string as literal (though in this case dot notation would read easier) or use a variable or calculate in some way.
So, these all set the myObj property named prop1 to the value Hello:
// quick easy-on-the-eye dot notation
myObj.prop1 = "Hello";
// brackets+literal
myObj["prop1"] = "Hello";
// using a variable
var x = "prop1";
myObj[x] = "Hello";
// calculate the accessor string in some weird way
var numList = [0,1,2];
myObj[ "prop" + numList[1] ] = "Hello";
Pitfalls:
myObj.[xxxx] = "Hello"; // wrong: mixed notations, syntax fail
myObj[prop1] = "Hello"; // wrong: this expects a variable called prop1
tl;dnr: If you want to compute or reference the key you must use bracket notation. If you are using the key explicitly, then use dot notation for simple clear code.
Note: there are some other good and correct answers but I personally found them a bit brief coming from a low familiarity with JS on-the-fly quirkiness. This might be useful to some people.
With lodash, you can create new object like this _.set:
obj = _.set({}, key, val);
Or you can set to existing object like this:
var existingObj = { a: 1 };
_.set(existingObj, 'a', 5); // existingObj will be: { a: 5 }
You should take care if you want to use dot (".") in your path, because lodash can set hierarchy, for example:
_.set({}, "a.b.c", "d"); // { "a": { "b": { "c": "d" } } }
First we need to define key as variable and then we need to assign as key as object., for example
var data = {key:'dynamic_key',value:'dynamic_value'}
var key = data.key;
var obj = { [key]: data.value}
console.log(obj)
Related to the subject, not specifically for jquery though. I used this in ec6 react projects, maybe helps someone:
this.setState({ [`${name}`]: value}, () => {
console.log("State updated: ", JSON.stringify(this.state[name]));
});
PS: Please mind the quote character.
With the advent of ES2015 Object.assign and computed property names the OP's code boils down to:
var obj = Object.assign.apply({}, $(itemsFromDom).map((i, el) => ({[el.id]: el.value})));
ajavascript have two type of annotation for fetching javascript Object properties:
Obj = {};
1) (.) annotation eg. Obj.id
this will only work if the object already have a property with name 'id'
2) ([]) annotation eg . Obj[id] here if the object does not have any property with name 'id',it will create a new property with name 'id'.
so for below example:
A new property will be created always when you write Obj[name].
And if the property already exist with the same name it will override it.
const obj = {}
jQuery(itemsFromDom).each(function() {
const element = jQuery(this)
const name = element.attr('id')
const value = element.attr('value')
// This will work
obj[name]= value;
})
If you want to add fields to an object dynamically, simplest way to do it is as follows:
let params = [
{ key: "k1", value: 1 },
{ key: "k2", value: 2 },
{ key: "k3", value: 3 },
];
let data = {};
for (let i = 0; i < params.length; i++) {
data[params[i].key] = params[i].value;
}
console.log(data); // -> { k1: 1, k2: 2, k3: 3 }
The 3 ways to access the object value
We can output the object value by passing in the appropriate key. Because I used emoji as the key in my example, it's a bit tricky. So let's look at a easier example.
let me = {
name: 'samantha',
};
// 1. Dot notation
me.name; // samantha
// 2. Bracket notation (string key)
me['name']; // samantha
// 3. Bracket notation (variable key)
let key = 'name';
me[key]; // samantha
know more
If you have object, you can make array of keys, than map through, and create new object from previous object keys, and values.
Object.keys(myObject)
.map(el =>{
const obj = {};
obj[el]=myObject[el].code;
console.log(obj);
});
objectname.newProperty = value;
const data = [{
name: 'BMW',
value: '25641'
}, {
name: 'Apple',
value: '45876'
},
{
name: 'Benz',
value: '65784'
},
{
name: 'Toyota',
value: '254'
}
]
const obj = {
carsList: [{
name: 'Ford',
value: '47563'
}, {
name: 'Toyota',
value: '254'
}],
pastriesList: [],
fruitsList: [{
name: 'Apple',
value: '45876'
}, {
name: 'Pineapple',
value: '84523'
}]
}
let keys = Object.keys(obj);
result = {};
for(key of keys){
let a = [...data,...obj[key]];
result[key] = a;
}
If I have an array like this:
var arr = ['one','two','three'];
I can access different parts by doing this:
console.log(arr[1]);
How can I access object properties by their order rather than by key?
Example:
var obj = {
'something' : 'awesome',
'evenmore' : 'crazy'
},
jbo = {
'evenmore' : 'crazy',
'something' : 'awesome'
};
How would I get the first property for each object–"something" from obj and "evenmore" from jbo–without explicitly using the property name?
Now, a few of you seem to think I'm after something like:
console.log(obj['something']);
This is not the case, I'm specifically looking to target the index, just like the first example - if it's possible.
"I'm specifically looking to target the index, just like the first example - if it's possible."
No, it isn't possible.
The closest you can get is to get an Array of the object's keys, and use that:
var keys = Object.keys( obj );
...but there's no guarantee that the keys will be returned in the order you defined. So it could end up looking like:
keys[ 0 ]; // 'evenmore'
keys[ 1 ]; // 'something'
The only way I can think of doing this is by creating a method that gives you the property using Object.keys();.
var obj = {
dog: "woof",
cat: "meow",
key: function(n) {
return this[Object.keys(this)[n]];
}
};
obj.key(1); // "meow"
Demo: http://jsfiddle.net/UmkVn/
It would be possible to extend this to all objects using Object.prototype; but that isn't usually recommended.
Instead, use a function helper:
var object = {
key: function(n) {
return this[ Object.keys(this)[n] ];
}
};
function key(obj, idx) {
return object.key.call(obj, idx);
}
key({ a: 6 }, 0); // 6
You can use the Object.values() method if you dont want to use the Object.keys().
As opposed to the Object.keys() method that returns an array of a given object's own enumerable properties, so for instance:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
Would print out the following array:
[ 'a', 'b', 'c' ]
The Object.values() method returns an array of a given object's own enumerable property values.
So if you have the same object but use values instead,
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
You would get the following array:
[ 'somestring', 42, false ]
So if you wanted to access the object1.b, but using an index instead you could use:
Object.values(object1)[1] === 42
You can read more about this method here.
var obj = {
'key1':'value',
'2':'value',
'key 1':'value'
}
console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])
// will not work
console.log(obj.2)
Edit:
"I'm specifically looking to target the index, just like the first example - if it's possible."
Actually the 'index' is the key. If you want to store the position of a key you need to create a custom object to handle this.
Yes, it is possible. We can define getters for each index, and return the property value, in the constructor method of the class. See this code.
class className {
constructor() {
this.name = "Bikram";
this.age = 8;
this.x = 89;
this.y = true;
//Use a for loop and define the getters (with the object property's index as its "name") for each property using Object.defineProperty()
for (let i = 0; i < Object.keys(this).length; i++) {
Object.defineProperty(this, i, {
get: function() {
return Object.values(this)[i]}
});
}
}
}
var b = new className();
console.log(b[0]); // same as b.name ("Bikram")
console.log(b[1]); // = b.age (8)
console.log(b[2]); // = b.x (89)
console.log(b[3]); // = b.y (true)
Edit: If you want to change the properties by their indices, which, of course, you do. Then, just define a corresponding setter for each property in the Object.defineProperty() method. It will look like:
// Insert this in place of the old one
Object.defineProperty(this, i, {
get: function() {
return Object.values(this)[i];
},
set: function(newValue) {
this[Object.keys(this)[i]] = newValue;
}
})
console.log(b[0]); // "Bikram"
b[0] = "Bikram Kumar";
console.log(b[0]); // "Bikram Kumar"
And now you have an "array-like-object" whose properties can be accessed or modified either by property key or its index :D
A side note: Notice that Object.keys() and Object.values() only return the enumerable properties. If you just declare a property and not assign it to any value, the Object.[key/value]s() methods will leave that in the returned array, because by default they are not enumerable. This might become confusing for the indices so defined (except the case the undeclared property is the last one).
To get around this, there is a simple way, if you want some property to have a index, but don't wanna assign it now. Just set it to undefined, and it will now be enumerable, and the indices won't be affected.
by jquery you can do this:
var arr = $.map(obj,function(value, key) {
return value;
});
alert(obj[0]);
Get the array of keys, reverse it, then run your loop
var keys = Object.keys( obj ).reverse();
for(var i = 0; i < keys.length; i++){
var key = keys[i];
var value = obj[key];
//do stuff backwards
}
you can create an array that filled with your object fields and use an index on the array and access object properties via that
propertiesName:['pr1','pr2','pr3']
this.myObject[this.propertiesName[0]]
I went ahead and made a function for you:
Object.prototype.getValueByIndex = function (index) {
/*
Object.getOwnPropertyNames() takes in a parameter of the object,
and returns an array of all the properties.
In this case it would return: ["something","evenmore"].
So, this[Object.getOwnPropertyNames(this)[index]]; is really just the same thing as:
this[propertyName]
*/
return this[Object.getOwnPropertyNames(this)[index]];
};
let obj = {
'something' : 'awesome',
'evenmore' : 'crazy'
};
console.log(obj.getValueByIndex(0)); // Expected output: "awesome"
Sure it is possible, but it is not as immediate as accessing to an array by its indexes, but still possible and even relatively simple actually: in fact you don't have to struggle too much. This code sample will show how:
var obj = {
'alfa' : 'value of obj the key alfa',
'beta' : 'value of obj the key beta',
'gamma' : 'value of obj the key gamma'
};
var jbo = {
'alfa' : 'value of jbo the key alfa',
'beta' : 'value of jbo the key beta',
'gamma' : 'value of jbo the key gamma'
};
alert ( obj[Object.keys(obj)[1]] );
alert ( jbo[Object.keys(jbo)[1]] );
/* you can even put it into a for loop as follows */
for (i=0;i<3;i++)
{
document.writeln ( "<br>This could be even a piece of HTML: " + obj[Object.keys(obj)[i]] );
document.writeln ( "<br>This could be even a piece of HTML: " + jbo[Object.keys(jbo)[i]] );
}
Explication:
As you know the Object.keys() statement returns an array of all enumerable properties (which means all keys) of the object you type into its round parenthesis.
So the only thing you need is to indicate the index after that array, which will returns the key literal found at that index.
The key itself is "digested" as usual by the object which returns the value at that key.
If you are not sure Object.keys() is going to return you the keys in the right order, you can try this logic instead
var keys = []
var obj = {
'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value3',
}
for (var key in obj){
keys.push(key)
}
console.log(obj[keys[1]])
console.log(obj[keys[2]])
console.log(obj[keys[3]])
You can also construct a function that will return the value of a property by accepting two parameters: the object and the "index" (order position)
function getValue(obj, index) {
let keysArray = Object.keys(obj)
let key = keysArray[index]
return obj[key]
}
Usage example getValue(obj, 2)
Snippet
let obj = {a: 'dog', b: 'cat', c: 'mouse'}
function getValue(obj, index){
let keysArray = Object.keys(obj)
let key = keysArray[index]
return obj[key]
}
console.log(getValue(obj, 2))
Let's say i have the following data
var obj = {
test: 'somedata',
scores: [
{
"points":99,
"id":"x12"
},
{
"points":21,
"id":"x13"
}
],
sites: [
{
"exercises":21,
"sid":"s12"
},
{
"exercises":23,
"sid":"s11"
}
],
history: {
key: 'value',
commits: [
{
id: 1,
value: 'thank you'
}
]
}
}
Notice that scores and sites contain arrays with unique elements based on id in scores and based on sid in sites. I want a function that does the following magic:
//will **update** obj.test to 'newdata' and return {test:'newdata'}
magicUpdate(obj, {test:'newdata'})
//will **insert** obj.newkey with with value 'value' and return {newkey: 'value'}
magicUpdate(obj, {newkey: 'value'})
//will do nothing and return {}
magicUpdate(obj, {scores: []})
//will **update** scores[0] and return {scores:[{points:3, id: "x12"}]}, as id "x12" is already in the array at index 0
magicUpdate(obj, {scores:[{points:3, id: "x12"}])
//will **insert** {points:3, id: "x14"} into obj.scores and return {scores:[{points:3, id: "x14"}]}
magicUpdate(obj, {scores:[{points:3, id: "x14"}]})
//will **update** sites[0] and return {sites:[{exercises:22, sid: "s12"}]}, as id "s12" is already in the array at index 0
magicUpdate(obj, {sites:[{exercises:22, sid: "s12"}])
//will **insert** {exercises:10, sid: "s14"} into obj.sites and return {sites:[{exercises:10, sid: "s14"}]}
magicUpdate(obj, {sites:[{exercises:10, sid: "s14"}]})
//and also be recursive ...
//will **update** obj.history.commits[0]
magicUpdate(obj, {'history.commits': [{id:1, value: 'changed'}]});
I have seen .update doing the recursion, but only if one is passing the path which should be determined automatically. Then there is .merge which internally uses _.baseMerge and comes really close to what i need though I do not understand the signature of the function.
_.merge(
{scores:[{id: 12, points:10}, {id: 13, points:10}]},
{scores:[{id: 14, points:10}, {id: 15, points:10}]}
)
// returns {scores:[{id: 14, points:10}, {id: 15, points:10}]} not the fully merged array
Can someone point me to a good direction or has achieved similar things with lodash?
The magicUpdate function you mention in your post could be achieved using lodash functions indeed.
For this implementation, I've used mostly _ .get, _ .set and _ .unionWith though I'm sure it could have been achieved using some others:
// src will be mutated. For simplicity's sake, obj is an object with only one property that represents the changes to make to src
function magicUpdate(src, obj) {
var key = _.first(_.keys(obj)),
value = _.get(obj, key),
srcValue = _.get(src, key),
comparator = function(a, b) {
var idKey = _.isUndefined(a.id) ? 'sid' : 'id';
return a[idKey] === b[idKey];
}
if (_.isArray(srcValue)) {
value = _.unionWith(value, srcValue, comparator);
}
return _.set(src, key, value);
}
As you may have noticed looking at the code, the return type is the mutated object and not what you're asking. I wasn't really sure what you wanted as a return value.
Anyway, Lodash doesn't have a built-in object difference function so it'd be necessary to develop something like that in case you wanted the difference between the old object and the modified one (you'd also have to _ .clone the object first to have a copy and be able to compare).
The idea of the function I present is to try to get the key of obj (it's the key we want to modify in src) and check if it exists and is an array. If so, we just add the two arrays, updating those in src that have the same id in obj. Due to the fact that sites, scores and history had id and sid I had to add some more logic to the comparator of the _.unionWith function.
If key doesn't exist or isn't an array, we just set it in src.
Here you have the fiddle in case you want to play with it. Hope it helps.
UPDATE
My first solution was intended for one property updated at a time. However, it seems that is possible to update more than one at the same time.
One quick solution could be to iterate over the object with the updates and update one property at a time.
function updateProperty(src, obj) {
var key = _.first(_.keys(obj)),
value = _.get(obj, key),
srcValue = _.get(src, key),
comparator = function(a, b) {
var idKey = _.isUndefined(a.id) ? 'sid' : 'id';
return a[idKey] === b[idKey];
}
if (_.isArray(srcValue)) {
value = _.unionWith(value, srcValue, comparator);
}
return _.set(src, key, value);
}
function magicUpdate(obj, src) {
_.forEach(src, function(value, key) {
updateProperty(obj, _.pick(src, key));
});
return obj;
}
Fiddle
I wrote a solution which is recursive and quite performant. See this fiddle.
function mergeRecursive(obj1, obj2) {
if (obj1.constructor == Array) {
for (var i = 0; i < obj1.length; i++) {
if (obj1[i].id == obj2.id) {
obj1[i] = obj2;
return obj1;
}
}
obj1.push(obj2);
return obj1;
}
for (var p in obj2) {
// Property in destination object set; update its value.
if (obj2[p].constructor == Array) {
obj2[p].forEach(function(arrayElement) {
obj1[p] = MergeRecursive(obj1[p], arrayElement);
});
} else if (obj2[p].constructor == Object) {
obj1[p] = MergeRecursive(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
}
return obj1;
}
This question already has answers here:
How do I check if an array includes a value in JavaScript?
(60 answers)
Closed 29 days ago.
I need to determine if an object already exists in an array in javascript.
eg (dummycode):
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};
carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);
now the "carBrands" array contains all instances.
I'm now looking a fast solution to check if an instance of car1, car2, car3 or car4 is already in the carBrands array.
eg:
var contains = carBrands.Contains(car1); //<--- returns bool.
car1 and car4 contain the same data but are different instances they should be tested as not equal.
Do I have add something like a hash to the objects on creation? Or is there a faster way to do this in Javascript.
I am looking for the fastest solution here, if dirty, so it has to be ;) In my app it has to deal with around 10000 instances.
no jquery
Use something like this:
function containsObject(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (list[i] === obj) {
return true;
}
}
return false;
}
In this case, containsObject(car4, carBrands) is true. Remove the carBrands.push(car4); call and it will return false instead. If you later expand to using objects to store these other car objects instead of using arrays, you could use something like this instead:
function containsObject(obj, list) {
var x;
for (x in list) {
if (list.hasOwnProperty(x) && list[x] === obj) {
return true;
}
}
return false;
}
This approach will work for arrays too, but when used on arrays it will be a tad slower than the first option.
Why don't you use the indexOf method of javascript arrays?
Check this out: MDN indexOf Arrays
Simply do:
carBrands.indexOf(car1);
It will return you the index (position in the array) of car1. It will return -1 if car1 was not found in the array.
http://jsfiddle.net/Fraximus/r154cd9o
Edit: Note that in the question, the requirements are to check for the same object referenced in the array, and NOT a new object. Even if the new object is identical in content to the object in the array, it is still a different object.
As mentioned in the comments, objects are passed by reference in JS and the same object can exist multiple times in multiple structures.
If you want to create a new object and check if the array contains objects identical to your new one, this answer won't work (Julien's fiddle below), if you want to check for that same object's existence in the array, then this answer will work. Check out the fiddles here and in the comments.
Having been recently bitten by the FP bug reading many wonderful accounts of how neatly the functional paradigm fits with Javascript
I replicate the code for completeness sake and suggest two ways this can be done functionally.
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};
var car5 = {name:'toyota'};
carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);
// ES6 approach which uses the includes method (Chrome47+, Firefox43+)
carBrands.includes(car1) // -> true
carBrands.includes(car5) // -> false
If you need to support older browsers use the polyfill, it seems IE9+ and Edge do NOT support it. Located in polyfill section of MSDN page
Alternatively I would like to propose an updated answer to cdhowie
// ES2015 syntax
function containsObject(obj, list) {
return list.some(function(elem) {
return elem === obj
})
}
// or ES6+ syntax with cool fat arrows
function containsObject(obj, list) {
return list.some(elem => elem === obj)
}
try Array.prototype.some()
MDN Array.prototype.some
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
You could use jQuery's grep method:
$.grep(carBrands, function(obj) { return obj.name == "ford"; });
But as you specify no jQuery, you could just make a derivative of the function. From the source code:
function grepArray( elems, callback, inv ) {
var ret = [];
// Go through the array, only saving the items
// that pass the validator function
for ( var i = 0, length = elems.length; i < length; i++ ) {
if ( !inv !== !callback( elems[ i ], i ) ) {
ret.push( elems[ i ] );
}
}
return ret;
}
grepArray(carBrands, function(obj) { return obj.name == "ford"; });
I used underscore javascript library to tweak this issue.
function containsObject(obj, list) {
var res = _.find(list, function(val){ return _.isEqual(obj, val)});
return (_.isObject(res))? true:false;
}
please refer to underscore.js documentation for the underscore functions used in the above example.
note: This is not a pure javascript solution. Shared for educational purposes.
You can just use the equality operator: ==. Objects are checked by reference by default, so you don't even need to use the === operator.
try this, just make sure you're using the correct variable reference in the place of car1:
var i, car, l = cars.length;
for (i = 0; i < l; i++)
{
if ((car = cars[i]) == car1)
{
break;
}
else car = null;
}
Edit to add:
An array extension was mentioned, so here's the code for it:
Array.prototype.contains = Array.prototype.contains || function(obj)
{
var i, l = this.length;
for (i = 0; i < l; i++)
{
if (this[i] == obj) return true;
}
return false;
};
Note that I'm caching the length value, as the Array's length property is actually an accessor, which is marginally slower than an internal variable.
I would use a generic iterator of property/value over the array. No jQuery required.
arr = [{prop1: 'val1', prop2: 'val2'}, {prop1: 'val3', prop2: 'val4'}];
objectPropInArray(arr, 'prop1', 'val3'); // <-- returns true
function objectPropInArray(list, prop, val) {
if (list.length > 0 ) {
for (i in list) {
if (list[i][prop] === val) {
return true;
}
}
}
return false;
}
You could try sorting the array based on a property, like so:
carBrands = carBrands.sort(function(x,y){
return (x == y) ? 0 : (x > y) ? 1 : -1;
});
Then you can use an iterative routine to check whether
carBrands[Math.floor(carBrands.length/2)]
// change carBrands.length to a var that keeps
// getting divided by 2 until result is the target
// or no valid target exists
is greater or lesser than the target, and so on, which will let you go through the array quickly to find whether the object exists or not.
try this ,
You can use the JavaScript some() method to find out if a JavaScript array contains an object.
<script>
// An array of objects
var persons = [{name: "Harry"}, {name: "Alice"}, {name: "Peter"}];
// Find if the array contains an object by comparing the property value
if(persons.some(person => person.name === "Peter")){
alert("Object found inside the array.");
} else{
alert("Object not found.");
}
</script>
EDIT 05/18/2022
The most simple way using ES6:
const arrayContainsObject = <T extends Record<string, unknown>>(array: T[], object: T) => {
return array.some(item => Object.keys(item).every(key => item[key] === object[key]))
}
Use like so:
const arr = [{
prop1: 'value1',
prop2: 'value2'
}]
const obj1 = {
prop1: 'value1',
prop2: 'value2'
}
const obj2 = {
prop2: 'value2',
prop1: 'value1'
}
const obj3 = {
prop0: 'value0',
prop1: 'value1'
}
arrayContainsObject(arr, obj1) // true
arrayContainsObject(arr, obj2) // true, even when props are arranged in different order
arrayContainsObject(arr, obj3) // false
Previous answer, don't use (because the order of props in an object needs to be identical)
const arr = [{
prop: 'value'
}]
const obj = {
prop: 'value'
}
arr.some((e) => Object.entries(e).toString() === Object.entries(obj).toString()) // true
i know this is an old post, but i wanted to provide a JQuery plugin version and my code.
// Find the first occurrence of object in list, Similar to $.grep, but stops searching
function findFirst(a,b){
var i; for (i = 0; i < a.length; ++i) { if (b(a[i], i)) return a[i]; } return undefined;
}
usage:
var product = $.findFirst(arrProducts, function(p) { return p.id == 10 });
This function is to check for a unique field.
Arg 1: the array with selected data
Arg 2: key to check
Arg 3: value that must be "validated"
function objectUnique( array, field, value )
{
var unique = true;
array.forEach(function ( entry )
{
if ( entry[field] == value )
{
unique = false;
}
});
return unique;
}
you can use Array.find().
in your case is going to look like this
carBrands.find(function(car){
let result = car.name === 'ford'
if (result == null){
return false;
} else {
return true
}
});
if car is not null it will return the javaScript Object which contains the string 'ford'
The issue with many of the answers here is that they will NOT find an object in an array that is equal to another object. They will only search for an EXISTING object that has a pointer to it in an array.
Quick fix using lodash to see if ANY equal object is in an array:
import _ from 'lodash';
_.find(carBrands, car1); //returns object if true, undefined if false
Working Plunker using this method: https://plnkr.co/edit/y2YX9o7zkQa2r7lJ
if its possible to use es6
carBrands.filter(carBrand => carBrand.name === carX.name).length > 0
if it's true there is a similarity
You can convert both the JSON objects to string and simply check if the bigger json contains the smaller json.
console.log(JSON.stringify(carBrands).includes(JSON.stringify(car1))); // true
console.log(JSON.stringify(carBrands).includes(JSON.stringify(car5))); // false
You could also a the findIndex
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
carBrands.push(car1);
if (carBrands.findIndex(f => f.name === car1.name) === -1) {
console.log('not contain')
} else {
console.log('contain')
}
if (carBrands.findIndex(f => f.name === car2.name) === -1) {
console.log('not contain')
} else {
console.log('contain')
}
How do I add new attribute (element) to JSON object using JavaScript?
JSON stands for JavaScript Object Notation. A JSON object is really a string that has yet to be turned into the object it represents.
To add a property to an existing object in JS you could do the following.
object["property"] = value;
or
object.property = value;
If you provide some extra info like exactly what you need to do in context you might get a more tailored answer.
var jsonObj = {
members:
{
host: "hostName",
viewers:
{
user1: "value1",
user2: "value2",
user3: "value3"
}
}
}
var i;
for(i=4; i<=8; i++){
var newUser = "user" + i;
var newValue = "value" + i;
jsonObj.members.viewers[newUser] = newValue ;
}
console.log(jsonObj);
A JSON object is simply a javascript object, so with Javascript being a prototype based language, all you have to do is address it using the dot notation.
mything.NewField = 'foo';
With ECMAScript since 2015 you can use Spread Syntax ( …three dots):
let people = { id: 4 ,firstName: 'John'};
people = { ...people, secondName: 'Fogerty'};
It's allow you to add sub objects:
people = { ...people, city: { state: 'California' }};
the result would be:
{
"id": 4,
"firstName": "John",
"secondName": "Forget",
"city": {
"state": "California"
}
}
You also can merge objects:
var mergedObj = { ...obj1, ...obj2 };
thanks for this post. I want to add something that can be useful.
For IE, it is good to use
object["property"] = value;
syntax because some special words in IE can give you an error.
An example:
object.class = 'value';
this fails in IE, because "class" is a special word. I spent several hours with this.
You can also use Object.assign from ECMAScript 2015. It also allows you to add nested attributes at once. E.g.:
const myObject = {};
Object.assign(myObject, {
firstNewAttribute: {
nestedAttribute: 'woohoo!'
}
});
Ps: This will not override the existing object with the assigned attributes. Instead they'll be added. However if you assign a value to an existing attribute then it would be overridden.
extend: function(){
if(arguments.length === 0){ return; }
var x = arguments.length === 1 ? this : arguments[0];
var y;
for(var i = 1, len = arguments.length; i < len; i++) {
y = arguments[i];
for(var key in y){
if(!(y[key] instanceof Function)){
x[key] = y[key];
}
}
};
return x;
}
Extends multiple json objects (ignores functions):
extend({obj: 'hej'}, {obj2: 'helo'}, {obj3: {objinside: 'yes'}});
Will result in a single json object
You can also dynamically add attributes with variables directly in an object literal.
const amountAttribute = 'amount';
const foo = {
[amountAttribute]: 1
};
foo[amountAttribute + "__more"] = 2;
Results in:
{
amount: 1,
amount__more: 2
}
You can also add new json objects into your json, using the extend function,
var newJson = $.extend({}, {my:"json"}, {other:"json"});
// result -> {my: "json", other: "json"}
A very good option for the extend function is the recursive merge. Just add the true value as the first parameter (read the documentation for more options). Example,
var newJson = $.extend(true, {}, {
my:"json",
nestedJson: {a1:1, a2:2}
}, {
other:"json",
nestedJson: {b1:1, b2:2}
});
// result -> {my: "json", other: "json", nestedJson: {a1:1, a2:2, b1:1, b2:2}}
Uses $.extend() of jquery, like this:
token = {_token:window.Laravel.csrfToken};
data = {v1:'asdass',v2:'sdfsdf'}
dat = $.extend(token,data);
I hope you serve them.
Following worked for me for add a new field named 'id'.
Angular Slickgrid usually needs such id
addId() {
this.apiData.forEach((item, index) => {
item.id = index+1;
});