How to check if the key exist in json array? - javascript

I have a json object, the structure of which is given below. I try to find if the key (for eg: 1 & 2) exist or not by myArray.includes('1') but it doesn't work. Is looping through the array the only way to check if attribute exist or not?
[{"1": [{}]},{"2": [{}]}]

The way to check if an object with a particular property exists or not would be to filter the objects by verifying if they have given property or not.
To check if an object contains a property you could use Array.prototype.includes on the list of keys obtained through Object.keys. Here's an example:
var data = [
{"1" : []},
{"2" : []}
];
// Count of objects containing a given key.
console.log(data.filter(t => Object.keys(t).includes("1")).length);
console.log(data.filter(t => Object.keys(t).includes("2")).length);
console.log(data.filter(t => Object.keys(t).includes("3")).length);

You have to loop through all of the elements in the Array and check if the key exists in each of those Objects.
arr.some(e => e.hasOwnProperty('1'));

You can use Array.some() which tests whether at least one element in the array passes the test.
const has1 = myArray.some(obj => obj.hasOwnProperty(“1”)); // Returns a boolean
const has2 = myArray.some(obj => obj.hasOwnProperty(“2”)); // Returns a boolean

You can use use some() and Object.prototype.hasOwnProperty()
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
let arr = [{
"1":[{}],
"2":[{}]
}]
let checkOne = arr.some(x => x.hasOwnProperty('1'));
let checkThree = arr.some(x => x.hasOwnProperty('3'));
console.log(checkOne) //true
console.log(checkThree) //false

You can try forEach to loop the keys of object and check if yours is there.
var obj = yourobject;
var mykey = 0;
Object.keys(obj).forEach(function(k){
if(k == mykey){
...
}
});

Related

How to check if values in array is present in object key of object array

I want to check if values in one array is present in object key of object array.
For example: arr = ["id1", "id2"]
objectArr = [{id: "id1"}]
I want to throw not found error in this case when id2 is not present in id of object array.
Help of any kind would be appreciated!
You can use filter and some for that:
var objectArr = [{id: "id1"}, {id: "id3"}]
var arr1 = ["id1", "id2"];
const notFounds = arr1.filter(el => !objectArr.some(obj => obj.id === el ));
console.log(notFounds); // ["id2"]
JS Array some:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
JS Array filter:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
If You iterate over objectArr, You can get object fields in form of array with: Object.entries(your_object).
for (const obj of objectArr) {
for (const item of Object.entries(obj)) {
// where item is field in object
// now You can compare if item is in [id1,id2]
}
}
You can try something like this
var arr = ["id1", "id2", "id3", "id4"];
var n = arr.includes("id2"); //true
For an array of objects. If the id is unique in the array
var arr = [{id:"id1"},{id:"id2"},{id:"id3"},{id:"id4"}]
const found = arr.some(el => el.id === "id3") // true
EDIT: ran.t has a better answer that keeps track of which ids are not found.
It sounds like what you're looking for is .every() method. Which will allow you can check each element in the array passes a given condition.
You can combine this with the .some() method to check at least one object in the objectArr has id equal to your element
const allElementsFound = ["id1", "id2"].every(el => objectArr.some(obj => obj.id === el))
if(!allElementsFound) {
// throw error
}

Getting object from array of objects matching values inside and array of dates with lodash

i have an array of obejcts that has this structure
let events = [ {
"initDate": "2019-11-20",
"finalDate": "2019-11-22",
"intermediateDates": [
"2019-11-20",
"2019-11-21"
],
"priority": 1
},....]
So, i'm trying to get the object that matches from a given array of dates for example :
let filteredDays = [
"2019-11-20",
"2019-11-21",
"2019-11-22"
]
i'm trying with lodash like this:
let eventsFound= [];
let intersection = _.map( this.events,function(value){
let inter = _.intersection(value.intermediateDates,filteredDates);
console.log(inter);
if(inter != []){
foundEvents.push(value);
return value;
}else{
return false;
}
});
when i console log inter i get the first array with values then the next arrays are empty but it keeps pushing all the events into the foundEvents Array and the returned array is the same as the events array.
You're comparing two arrays using !=. In javascript [] != [] is always true. To check if an array is empty, use length property like arr.length == 0.
Use filter instead of using map like a forEach.
To check existance use some/includes combo instead of looking for intersections.
So, filter events that some of its intermediateDates are included in filteredDates:
let eventsFound = _.filter(this.events, event =>
_.some(event.intermediateDates, date =>
_.includes(filteredDates, date)
)
);
The same using native functions:
let eventsFound = this.events.filter(event =>
event.intermediateDates.some(date =>
filteredDates.includes(date)
)
);

Find index of object in javascript using its property name

I want to find Index of javascript array of objects using objects property name. My code is :-
const checkbox = [{'mumbai': true},{'bangalore': true},{'chennai': true},{'kolkata': true}];
How can i find index of chennai? Can i acheive using lodash?
You can use .findIndex()
const checkbox = [
{'mumbai': true},
{'bangalore': true},
{'chennai': true},
{'kolkata': true}
];
const finder = (arr, key) => arr.findIndex(o => key in o);
console.log(finder(checkbox, 'chennai'));
console.log(finder(checkbox, 'kolkata'));
console.log(finder(checkbox, 'delhi'));
checkbox.map((v,i) => Object.keys(v).indexOf("chennai") !== -1 ? i : -1).filter(v => v !== -1)[0]
Will give you the index of "chennai", replace it with any other key to get a different index.
What this does is:
Map the array to an array indicating only indices which contain objects with the wanted key
Filter only the indices which you want
Get the first one (you can use the rest as well if there are multiple entries matching your search)
This works in every browser since it only uses .map() , Object.keys() and .filter()

How to edit value of an object using the reference?

I have a big object array persons
persons = [{name:'john1'}, {name:'john2'},...]
I iterated the array and found the object I am interested to edit
objectToEdit = persons .find((person)=>person.name==='john1')
Now I created an edited object in immutable way (someOtherPerson = {name:'johnxx'})
objectFinal = {...objectToEdit, someOtherPerson}
Now I want to replace this objectFinal with objectToEdit in persons array, without having to traverse the array again. But doing objectToEdit =objectFinal , will just assign objectToEdited's reference to objectToEdit , without making any change in the persons array
Is there a clean way to achieve this without traversing the array?
Edit:
In this example, the object in persons jave just one key (i.e, name). This is to make question minimal. In my project, I have more than 30 keys.
If you want to edit an object in a list,in place, use Array.prototype.some
var persons = [{
name: 'john1'
}, {
name: 'jack5'
}]
var someOtherPerson = {
name: 'johnxx'
}
persons.some(function(person) {
// if condition, edit and return true
if (person.name === 'john1') {
// use Object.keys to copy properties
Object.keys(someOtherPerson).forEach(function(key) {
person[key] = someOtherPerson[key]
})
// or use assign to merge 2 objects
Object.assign(person, someOtherPerson);
return true // stops iteration
}
})
console.log(JSON.stringify(persons))
If you want to avoid mutating the objects in the original array, you might use .findIndex instead, and reassign the item in the array at that index:
const persons = [{name:'john1'}, {name:'john2'}];
const objectToEditIndex = persons.findIndex((person) => person.name === 'john1');
const someOtherPerson = {name:"johnxx"};
persons[objectToEditIndex] = {
...persons[objectToEditIndex],
...someOtherPerson
};
console.log(persons);
Doing this:
objectFinal = {...objectToEdit, someOtherPerson}
you lose the reference to the original objectToEdit object. To edit it, you can do
`objectToEdit.value = otherValue`.
PS: Having said that, you only lose reference to the first level object. If that object, contains another object or array, you have reference to it:
objectFinal.innerObject.value = otherValue;
{name:'john1'} should be replace with {name:"johnxx"} in persons
Reassign persons to the persons-array mapped with the new value:
let persons = [{name:'john1'}, {name:'john2'}];
persons = persons.map( v => v.name === "john1" ? {name: "johnxx"} : v );
console.log(persons);
Or, if you're worried about performance, use Array.splice in combination with Array.findIndex
The findIndex method executes the callback function once for every
array index 0..length-1 (inclusive) in the array until it finds one
where callback returns a truthy value (a value that coerces to true).
If such an element is found, findIndex immediately returns the index
for that iteration.
let persons = [{name:'john1'}, {name:'john2'}];
persons.splice(persons.findIndex( v => v.name==="john1" ), 1, {name:'johnxx'});
console.log(persons);
Or use a utility method (snippet for a large array (1,000,000 elements) and with performance timer)
// replacer method
const replace = (obj, [key, value], replacement) => {
obj.splice(persons.findIndex( v => v[key] === value ), 1, replacement);
return obj;
}
// create a large array (this may take some extra time)
let persons = Array.from({length: 1000000}).map(v =>
({name: Math.floor(100000 + Math.random() * 1000000000).toString(16)}) );
// pick an entry
const someEntry = Math.floor(persons.length * Math.random());
const entry = Object.entries(persons[someEntry])[0];
console.log("before:", persons[someEntry]);
const t = performance.now();
// replacement call here
console.log("after:", replace(persons, entry, {name: "johnxx"})[someEntry]);
console.log("replacement took:", `${((performance.now() - t)/1000).toFixed(3)} sec`);

Cannot get/fetch keys from an array in javascript

I have an array object where there are key value pairs. I am trying to get the keys in that array using a loop but I am getting only 0. What is the problem with my code.
var strj = '{"name":"John","age":"30","cars":
[ {"type":"car", "year":"1998"},
{"type":"van", "year":"1995"}]}';
var myobj = JSON.parse(strj)
var care = myobj.cars.filter(c => c.type=='car');
Value of care
0:{type: "car", year: "1998"}
length:1
__proto__:Array(0)
Loop
for (var key in care){
if(care.hasOwnProperty(key)){
console.log(key)
}
}
care is a array type so you cannot do for (var key in care). You need to do for (var key in care[0]). This is because for (var key in care) will look for the key value in care and since it is a array it will always take 0 as a value in key(as you have only one object in array and its index is 0). That is why you got 0 in console.log.
var care =[{type: "car", year: "1998"}];
for (var key in care[0]){
if(care[0].hasOwnProperty(key)){
console.log(key)
}
}
care.forEach( ( singleCar ) => {
for ( var key in singleCar ){
console.log(key);
if( care.hasOwnProperty( key ) ){
console.log(key);
}
}
})
forEach will give you all the objects one by one. so you can check them.
As others have solved the issue, might i make a suggestion - Object.keys () gives an array of the keys for a given object. Since you are getting your filtered object and simply want its keys - the following will achieve that. Note that this is only using the code after you have filtered the original and have gained the "care" object.
As an aside, note that object.values() will give you an array of the values in a given object and object.entries() will give you arrays of the key / value pairing.
var care = {type: "car", year: "1998"};
var keys = Object.keys(care)
console.log(keys) // gives ["type","year"]
filter() method returns a Array of matches.
var care = myobj.cars.filter(c => c.type=='car'); // So, this returns an array.
care.forEach(element => {
console.log(Object.keys(element)); //Prints keys of each element
});
Well actually there is no problem in your code at all. But you just misunderstood the use of javascript filter. Javascript filter() creates new array that's why you are getting 0 as key. If you want to get only one matching element then find() is what you should use.
var strj = '{"name":"John","age":"30","cars":[{"type":"car", "year":"1998"},{"type":"van", "year":"1995"}]}';
var myobj = JSON.parse(strj)
var care = myobj.cars.filter(c => c.type == 'car'); // returns array
var care = myobj.cars.find(c => c.type == 'car'); // returns first matching object
var care = myobj.cars.findIndex(c => c.type == 'car'); // returns first matching index
Javascript filter() method => Read Here
Javascript find() => Read Here
Javascript findIndex() method => Read Here

Categories

Resources