Set property on object while iterating - javascript

I am making a SPA with Laravel(backend) and Vue.js. I have the following arrays:
accessArray:
["BIU","CEO","Finance","HRD","Group"]
access:
["BIU","Group"]
I want to compare the access array to the accessArray array and if there is a match to change the record (in the accessArray) and add a true value otherwise add a false value. I am doing this inside a Vue method.
... so far I got this:
var foo = ["BIU","CEO","Finance","HRD","Group"];
var bar = ["BIU","Group"];
$.each(bar, function (key, value) {
if ($.inArray(value, foo) != -1) {
var position = $.inArray(value, foo);
console.log(value + ' is in the array. In position ' + position);
foo[position] = {name: value, checked: true};
}
});
Which outputs this to the console:
BIU is in the array. In position 0
Group is in the array. In position 4
And this in Vue:
[
{"name":"BIU","checked":true},
"CEO",
"Finance",
"HRD",
{"name":"Group","checked":true}
]
The output I would like to achieve is the following:
[
{"name":"BIU","checked":true},
{"name":"CEO","checked":false},
{"name":"Finance","checked":false},
{"name":"HRD","checked":false},
{"name":"Group","checked":true}
]
Any help would be greatly appreciated, I have looked at many similar problems on SO but cant seem to find anything along these lines. I have also tried to add an else statement on the end but I (think) I'm converting it to an object so that doesn't seem to work.
Edit:
The data in foo comes from a Laravel config setting so is somewhat dynamic
The data in bar is JSON received from the Laravel ORM (its json stored in a text field)

An option with vanilla javascript:
var foo = ["BIU","CEO","Finance","HRD","Group"];
var bar = ["BIU","Group"];
var result = foo.map(name => {
var checked = bar.indexOf(name) !== -1
return { name, checked }
})
console.log(result)

You can use Array#map to iterate over the array and construct a new one, by checking if values are present in the other one through Array#includes
const accessArray = ["BIU","CEO","Finance","HRD","Group"];
const access = [ "BIU", "Group" ];
const result = accessArray.map( a => ({ name: a, checked: access.includes(a)}) ) ;
console.log(result);
A note: when using an arrow function and you want to return an object, you need to surround the object literal in () otherwise it would be interpreted as a code block.

Use reduce and inside the reduce call back check if the item is present in both accessArray & access . Create an object and the item present in both array set the value of checked to true or false
let arr1 = ["BIU", "CEO", "Finance", "HRD", "Group"]
let arr2 = ["BIU", "Group"];
let k = arr1.reduce(function(acc, curr) {
let obj = {}
if (arr2.includes(curr)) {
obj.name = curr;
obj.checked = true
} else {
obj.name = curr;
obj.checked = false
}
acc.push(obj);
return acc;
}, []);
console.log(k)

To achieve expected result use below option
1. Loop foo array
2.Remove initial if condition - "if ($.inArray(value, foo) != -1)" to loop through all
3. Do conditional check for checked - checked: $.inArray(value, bar) !== -1 ? true : false
codepen - https://codepen.io/nagasai/pen/GXbQOw?editors=1011
var foo = ["BIU","CEO","Finance","HRD","Group"];
var bar = ["BIU","Group"];
$.each(foo, function (key, value) {
foo[key] = {name: value, checked: $.inArray(value, bar) !== -1 ? true : false};
});
console.log(foo);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Option 2:
Without using jquery and using simple forEach to loop through foo
codepen - https://codepen.io/nagasai/pen/YOoaNb
var foo = ["BIU","CEO","Finance","HRD","Group"];
var bar = ["BIU","Group"];
foo.forEach((v,i) => foo[i] = {name: v , checked : bar.includes(v)})
console.log(foo);

Related

Indexing a JSON by index instead of key? [duplicate]

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))

Javascript array find check for undeifned

I am using javascript array.find on my list of object arrays. I want to get another property of that object only when compared to that
property is available.
When compared to t, I get value as 'Value1'
When compared to t1, I get undefined. I want to check for 'undefined' and get the value only when available.
const t = 'abc';
const t1= 'xyz';
temp = [ {key: "abc", value: "Value1}]
temp.find( check => check.key === t ).value);
Depending on how you intend to use the value, you will likely find you need some type of value as a result of your search. This will allow you to substitute something or nothing as needed.
const t = 'abc';
const t1= 'xyz';
temp = [ {key: "abc", value: "Value1"}]
const result = temp.find( check => check.key === t1 ) || {value:'Not Found!'};
console.log(result.value);
Firstly, you were missing a closing quote. Secondly, use some and find:
const t = 'abc';
const t1= 'xyz';
const temp = [{key: "abc", value: "Value1"}];
if (temp.some(({ key }) => key == t)) console.log(temp.find(({ key }) => key == t).value);
If you want it to throw an error, return undefined, return a default or something else, you can check for undefined like so:
x = list.find(logic)
if(x){
//carry on as normal
else{
//handle it not being found
}

Access sub-property with generic/dynamic property list [duplicate]

I have a bunch of object attributes coming in as dot-delimited strings like "availability_meta.supplier.price", and I need to assign a corresponding value to record['availability_meta']['supplier']['price'] and so on.
Not everything is 3 levels deep: many are only 1 level deep and many are deeper than 3 levels.
Is there a good way to assign this programmatically in Javascript? For example, I need:
["foo.bar.baz", 1] // --> record.foo.bar.baz = 1
["qux.qaz", "abc"] // --> record.qux.qaz = "abc"
["foshizzle", 200] // --> record.foshizzle = 200
I imagine I could hack something together, but I don't have any good algorithm in mind so would appreciate suggestions. I'm using lodash if that's helpful, and open to other libraries that may make quick work of this.
EDIT this is on the backend and run infrequently, so not necessary to optimize for size, speed, etc. In fact code readability would be a plus here for future devs.
EDIT 2 This is NOT the same as the referenced duplicate. Namely, I need to be able to do this assignment multiple times for the same object, and the "duplicate" answer will simply overwrite sub-keys each time. Please reopen!
You mentioned lodash in your question, so I thought I should add their easy object set() and get() functions. Just do something like:
_.set(record, 'availability_meta.supplier.price', 99);
You can read more about it here: https://lodash.com/docs#set
These functions let you do more complex things too, like specify array indexes, etc :)
Something to get you started:
function assignProperty(obj, path, value) {
var props = path.split(".")
, i = 0
, prop;
for(; i < props.length - 1; i++) {
prop = props[i];
obj = obj[prop];
}
obj[props[i]] = value;
}
Assuming:
var arr = ["foo.bar.baz", 1];
You'd call it using:
assignProperty(record, arr[0], arr[1]);
Example: http://jsfiddle.net/x49g5w8L/
What about this?
function convertDotPathToNestedObject(path, value) {
const [last, ...paths] = path.split('.').reverse();
return paths.reduce((acc, el) => ({ [el]: acc }), { [last]: value });
}
convertDotPathToNestedObject('foo.bar.x', 'FooBar')
// { foo: { bar: { x: 'FooBar' } } }
Just do
record['foo.bar.baz'] = 99;
But how would this work? It's strictly for the adventurous with a V8 environment (Chrome or Node harmony), using Object.observe. We observe the the object and capture the addition of new properties. When the "property" foo.bar.baz is added (via an assignment), we detect that this is a dotted property, and transform it into an assignment to record['foo']['bar.baz'] (creating record['foo'] if it does not exist), which in turn is transformed into an assignment to record['foo']['bar']['baz']. It goes like this:
function enable_dot_assignments(changes) {
// Iterate over changes
changes.forEach(function(change) {
// Deconstruct change record.
var object = change.object;
var type = change.type;
var name = change.name;
// Handle only 'add' type changes
if (type !== 'add') return;
// Break the property into segments, and get first one.
var segments = name.split('.');
var first_segment = segments.shift();
// Skip non-dotted property.
if (!segments.length) return;
// If the property doesn't exist, create it as object.
if (!(first_segment in object)) object[first_segment] = {};
var subobject = object[first_segment];
// Ensure subobject also enables dot assignments.
Object.observe(subobject, enable_dot_assignments);
// Set value on subobject using remainder of dot path.
subobject[segments.join('.')] = object[name];
// Make subobject assignments synchronous.
Object.deliverChangeRecords(enable_dot_assignments);
// We don't need the 'a.b' property on the object.
delete object[name];
});
}
Now you can just do
Object.observe(record, enable_dot_assignments);
record['foo.bar.baz'] = 99;
Beware, however, that such assignments will be asynchronous, which may or may not work for you. To solve this, call Object.deliverChangeRecords immediately after the assignment. Or, although not as syntactically pleasing, you could write a helper function, also setting up the observer:
function dot_assignment(object, path, value) {
Object.observe(object, enable_dot_assignments);
object[path] = value;
Object.deliverChangeRecords(enable_dot_assignments);
}
dot_assignment(record, 'foo.bar.baz', 99);
Something like this example perhaps. It will extend a supplied object or create one if it no object is supplied. It is destructive in nature, if you supply keys that already exist in the object, but you can change that if that is not what you want. Uses ECMA5.
/*global console */
/*members split, pop, reduce, trim, forEach, log, stringify */
(function () {
'use strict';
function isObject(arg) {
return arg && typeof arg === 'object';
}
function convertExtend(arr, obj) {
if (!isObject(obj)) {
obj = {};
}
var str = arr[0],
last = obj,
props,
valProp;
if (typeof str === 'string') {
props = str.split('.');
valProp = props.pop();
props.reduce(function (nest, prop) {
prop = prop.trim();
last = nest[prop];
if (!isObject(last)) {
nest[prop] = last = {};
}
return last;
}, obj);
last[valProp] = arr[1];
}
return obj;
}
var x = ['fum'],
y = [
['foo.bar.baz', 1],
['foo.bar.fum', new Date()],
['qux.qaz', 'abc'],
['foshizzle', 200]
],
z = ['qux.qux', null],
record = convertExtend(x);
y.forEach(function (yi) {
convertExtend(yi, record);
});
convertExtend(z, record);
document.body.textContent = JSON.stringify(record, function (key, value, Undefined) {
/*jslint unparam:true */
/*jshint unused:false */
if (value === Undefined) {
value = String(value);
}
return value;
});
}());
it's an old question, but if anyone still looking for a solution can try this
function restructureObject(object){
let result = {};
for(let key in object){
const splittedKeys = key.split('.');
if(splittedKeys.length === 1){
result[key] = object[key];
}
else if(splittedKeys.length > 2){
result = {...result, ...{[splittedKeys.splice(0,1)]: {}} ,...restructureObject({[splittedKeys.join('.')]: object[key]})}
}else{
result[splittedKeys[0]] = {[splittedKeys[1]]: object[key]}
}
}
return result
}

Easiest way to fill array with an object in JavaScript without coding a loop?

Say I have the following object:
var obj = { foo: 'bar' };
I want to add this object to an array X amount of times so the result is:
[{ foo: 'bar' }, { foo: 'bar'}, ... , { foo: 'bar'}]
Is there a way to accomplish this without explicitly coding a loop?
There is a way: manually. Any programmatic solution will indeed use a loop here, which, if you wish to maintain your sanity -- use it.
You can use map
var filled = Array.apply(null, Array(501)).map(function() { return {"foo":"bar"} });
You can do this using .fill
const someArray = ['test']; // Any other data you may have
const resultingArray = new Array(100).fill({ foo: 'bar' }).concat(someArray);
Set 100 to whatever number you need, concat any extra data after (or before if needed)
As #isvforall pointed out this isn't a deep copy and is done via reference so changing any of the elements in the array would affect all of the others which reference the same object. Best used if your values are primitives.
I think epascarello's answer is already a winner, and I +1'd it, but here's another approach just for kicks, using your Array.join() trick along with JSON.stringify() and JSON.parse().
Verbose:
var obj = { foo: 'bar' };
var objJSON = JSON.stringify(obj);
var list = new Array(501).join(objJSON + ',')
var trimmedList = list.substr(0, list.length - 1); // getting rid of that last comma
var arrayJSON = '[' + trimmedList + ']';
var array = JSON.parse(arrayJSON);
console.log(array);
Compact:
var list = new Array(501).join(JSON.stringify({ foo: 'bar' }) + ',')
var array = JSON.parse('[' + list.substr(0, list.length - 1) + ']');
console.log(array);
If you really don't want a loop you can use recursion.
function objFillArray(obj, count) {
let ret = [];
return notALoop();
function notALoop() {
ret.push(obj);
if( --count ) return notALoop();
return ret;
}
}
this will keep calling notALoop count number of times adding the object to the returned array.
Using recursion and concat function
var obj = { foo: 'bar' };
var result = (function fill(a, len) {
return a.length == len ? a : fill(a.concat(obj), len);
})([], 10);
var obj = { foo: 'bar' };
var result = (function fill(a, len) {
return a.length == len ? a : fill(a.concat(obj), len);
})([], 10);
document.write(JSON.stringify(result));
The callback function in Array.from can be used to ensure each element of the array is a different reference.
const arr = Array.from({length: 5}, _=>({foo: 'bar'}));
console.log(arr);
If all elements are meant to be the same reference, directly use Array#fill.
const arr = Array(5).fill({foo: 'bar'});
console.log(arr);
Use .push() function to assign value to an array.
yourarray.push(yourobject);
|
|
|
V
fiveHundredChars.push(obj);

How to determine if object is in array [duplicate]

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')
}

Categories

Resources