How to verify Array of objects is empty/null/undefined in js - javascript

I have a js array of objects as follows:
var person = [{
firstName: "",
lastName: "Doe",
age: 46
}, {
firstName: "John",
lastName: "",
age: 35
}];
How do i find out if at least of the objects in the array, for eg firstName: or lastName: is empty or not? The result of the called function needs only to be true or false.

You can use filter & length like:
const isEmpty = person.filter(x => !x.firstName || !x.lastName).length > 0
Or, using some like:
const isEmpty = person.some(x => !x.firstName || !x.lastName);
EDIT:-
function filterItems(TableData) {
return TableData.filter(function(el) {
return Object.values(el).some(v => !v);
})
}

You can use forEach to iterate over the array and use Object.values to get all the value. Then use indexOf to test if the value matches.Use a variable to save the state
var person = [{
firstName: "",
lastName: "Doe",
age: 46
},
{
firstName: "John",
lastName: "",
age: 35
}
];
function testArray(arr) {
var isEmpty = false
arr.forEach(function(item) {
if (Object.values(item).indexOf("") !== -1) {
isEmpty = true
}
})
return isEmpty;
}
console.log(testArray(person))

If at least one item is null or empty, it returns false
const person = [{
firstName: "",
lastName: "Doe",
age: 46
}, {
firstName: "John",
lastName: "",
age: 35
}];
const allItemsHaveValue = person.map(o => Object.values(o).every(v => v)).every(v => v);
console.log('All items have value: ', allItemsHaveValue);

Related

Accumulator of reduce function undefined if not returned. Why does it behave like this?

Array to be reduced:
const users = [
{ firstname: "Sanket", lastname: "Shevkar", age: 22 },
{ firstname: "Aniket", lastname: "Bhalla", age: 45 },
{ firstname: "Tanvi", lastname: "Shinde", age: 21 },
{ firstname: "Saif", lastname: "Siddiqi", age: 67 },
];
const outout = users.reduce((acc, curr)=>{
if(curr.age<45){
acc.push(curr.firstname);
}
}, [])
Throws TypeError:
Uncaught TypeError: Cannot read property 'push' of undefined
I have passed an empty array to initialize the acc (accumulator), but still it throws typeError. If I return acc at the end, it works perfectly.
const outout = users.reduce((acc, curr)=>{
if(curr.age<45){
acc.push(curr.firstname);
}
return acc;
}, [])
Can someone explain this behaviour?
Array.reduce must return accumulator on every loop
const users = [
{ firstname: "Sanket", lastname: "Shevkar", age: 22 },
{ firstname: "Aniket", lastname: "Bhalla", age: 45 },
{ firstname: "Tanvi", lastname: "Shinde", age: 21 },
{ firstname: "Saif", lastname: "Siddiqi", age: 67 },
];
const outout = users.reduce((acc, curr)=>{
if(curr.age<45){
return acc.concat(curr.firstname);
}
return acc
}, [])
console.log(outout)

Remove all fields except some

Create a function, which removes all fields except 'firstName' and 'lastName' from the objects.
This is the code I've written. Any recommendations?
let people = [
{
firstName: 'John',
lastName: 'Clark',
gender: 'male'
},
{
firstName: 'Kaily',
lastName: 'Berserk',
gender: 'female'
},
{
firstName: 'Steven',
lastName: 'Bergeron',
gender: 'male'
}
];
function removeAllExceptNames(arr) {
let first = 'firstName';
let last = 'lastName';
return arr.forEach(p => {
if (p !== first || p !== last) {
delete arr[p];
}
})
}
console.log(removeAllExceptNames(people));
console.log(people);
I have 2 arguments in the function, the arr and the names
arr is the given array, names is the list of fields you want to keep in the array
I used forEach twice.. the first time was for the arr, the second time was for the Object's keys for each index in arr and that is where the exception names can be related to fields in the array of objects
let people = [
{
firstName: 'John',
lastName: 'Clark',
gender: 'male'
},
{
firstName: 'Kaily',
lastName: 'Berserk',
gender: 'female'
},
{
firstName: 'Steven',
lastName: 'Bergeron',
gender: 'male'
}
];
function removeAllExceptNames(arr,names) { //arr is the same, names is a list of names you want to keep
arr.forEach(a=>{
Object.keys(a).forEach(b=>{
if(!names.includes(b)){delete(a[b])}
})
})
}
removeAllExceptNames(people,["firstName","lastName"]);
console.log(people);
You can make use of map along with Object.fromEntries to get the expected output:
const people = [ { firstName: 'John', lastName: 'Clark', gender: 'male' }, { firstName: 'Kaily', lastName: 'Berserk', gender: 'female' }, { firstName: 'Steven', lastName: 'Bergeron', gender: 'male' }];
const keepProp=(arr, keepProp)=>arr.map(o=>Object.fromEntries(keepProp.map(n=>[n,o[n]])));
console.log(keepProp(people, ['firstName','lastName']))
I think we need to understand what the keyword delete does. The Mozilla Foundation says
The JavaScript delete operator removes a property from an object; if no more references to the same property are held, it is eventually released automatically.
In your scenario, you successfully removed the reference but the list is not re-ordered. It only gets replaced with an undefined. We can achieve the same thing by using the splice array function. This will remove the element and re-order.
function removeAllExceptNames(arr,firstName,lastName) {
let instancesOfNamesInArray = arr.filter(e => e.firstName == firstName || e.lastName == lastName);
// We loop through this instances and remove them from the array
instancesOfNamesInArray.foreach((item) => {
arr.splice(arr.indexOf(item),1); // Will remove the item from the array
});
}

How to filter full name string properly in Javascript?

So i have an array of objects which I want to filter with a search input.
const people = [
{
firstName: 'John',
lastName: 'Doe',
},
{
firstName: 'Jane',
lastName: 'Doe',
}
];
I made this function to take a list and a search value so It could return filtered list.
const filterList = (list, searchValue) => {
let filtered = list.filter(item => {
let fullName = item.firstName.toLowerCase() + item.lastName.toLowerCase()
let trimmedSearchValue = searchValue.replace(/\s+/g, '');
return fullName.includes(trimmedSearchValue.toLowerCase())
})
return filtered
}
Filtering works when I call it like this
console.log(filterList(people, 'john'))
// returns { firstName: "John", lastName: "Doe"}
console.log(filterList(people, 'jane'))
// returns { firstName: "Jane", lastName: "Doe"}
console.log(filterList(people, 'doe'))
// returns both objects [
// { firstName: "John", lastName: "Doe"},
// { firstName: "Jane", lastName: "Doe"}
// ]
But when I call it like this I get empty array as a result
console.log(filterList(people, 'doe j'))
//returns empty array [], expected to get back both objects
console.log(filterList(people, 'doe john'))
//returns empty array [], expected to get {firstName: "John", lastName: "Doe"}
I think I am not correctly comparing fullName with searchValue but I couldn't figure it out.
You can compare with the lastName+firstName as well:
const filterList = (list, searchValue) => {
return list.filter(item => {
const fullName = `${item.firstName}${item.lastName}`.toLowerCase();
const reversedFullName = `${item.lastName}${item.firstName}`.toLowerCase();
const trimmedSearchValue = searchValue.replace(/\s+/g, '').toLowerCase();
return fullName.includes(trimmedSearchValue) || reversedFullName.includes(trimmedSearchValue);
});
}
const people = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Doe' }
];
console.log(filterList(people, 'doe j'));
console.log(filterList(people, 'doe john'));
You can do something like this:
const people = [
{
firstName: 'John',
lastName: 'Doe',
},
{
firstName: 'Jane',
lastName: 'Doe',
}
];
const filterList = (list, searchValue) => {
let filtered = list.filter(item => {
const arr = searchValue.split(' ');
return arr.some(el => item.firstName.toLowerCase().includes(el) || item.lastName.toLowerCase().includes(el));
})
return filtered
}
console.log(filterList(people, 'doe j'))
This should do the job too:
const people = [{firstName: 'John',lastName: 'Doe'},
{firstName: 'Jane',lastName: 'Doe'}];
function find(arr,pat){
let pa=pat.trim().replace(/ +/g," ").split(" ")
.map(p=>new RegExp(p,"i"));
return arr.filter(n=>{
let name=n.firstName+" "+n.lastName;
return pa.every(p=>p.test(name))
})
}
["doe j","john","jan do"].forEach(t=> // test cases ...
console.log(find(people,t))
)

Search javascript object for any value

I have an array of objects. I'd like to run a global search accross all values within each object and return that object.
Data
const data = [
{
firstName: 'Brady',
lastName: 'Smith'
},
{
firstName: 'Jason',
lastName: 'Brady'
},
{
firstName: 'Michael',
lastName: 'Bolten'
}
];
How do I search for Brady across all values to return both Brady Smith and Jason Brady objects? If there is an es6 way that would be great.
Current attempt
const filteredData = data
.map(item => {
if (Object.values(item) === 'Brady') {
return item;
}
})
.filter(function(element) {
return element != null;
});
No need to map the array.
You can use filter and includes to check if a string is on the array.
const data = [{
firstName: 'Brady',
lastName: 'Smith'
},
{
firstName: 'Jason',
lastName: 'Brady'
},
{
firstName: 'Michael',
lastName: 'Bolten'
}
];
const filteredData = data.filter(o => Object.values(o).includes('Brady'));
console.log(filteredData);
You can simply use filter and find
const data = [{firstName: 'Brady',lastName: 'Smith'},{firstName: 'Jason',lastName: 'Brady'},{firstName: 'Michael',lastName: 'Bolten'}];
const filteredData = data.filter(data=>
Object.values(data).some(val=> val === 'Brady')
)
console.log(filteredData)

How to check if objects in an array of objects all have specific structure and are not a null?

I receive an array of objects from the server. But my app breaks because some objects do not have a structure just a null value and my logic depends on checking against certain object keys to do one thing or another. Here is an example of an array that i receive:
[{
clienTnames: {
firstName: 'Jack',
lastName: 'Jackson'
}
}, {
clienTnames: {
firstName: 'John',
lastName: 'Johnson'
}
}, {
clienTnames: null
}]
I would like to check if any objects arrive as null and if they do switch them to empty object with all the proper keys just with no value. So if I receive clienTnames: null; I would like to automatically change it to clienTnames : {firstName: ' ', lastName: ' '}
Just use a map function:
names = names.map(name => {
return name.clienTnames
? name.clienTnames
: { clienTnames: { firstName: '', lastName: '' } }
});
You can create a defaultObj with all the default properties. Then loop through the array and update items which have clienTnames property set to null
let array = [{clienTnames:{firstName:'Jack',lastName:'Jackson'}},{clienTnames:{firstName:'John',lastName:'Johnson'}},{clienTnames:null}]
const defaultObj = {
firstName: '',
lastName: ''
}
array.forEach(a => {
if(!a.clienTnames)
a.clienTnames = { ...defaultObj }
})
console.log(array)
You can do something like this:
const data = [{ clienTnames: { firstName: 'Jack', lastName: 'Jackson' } }, { clienTnames: { firstName: 'John', lastName: 'Johnson' } }, { clienTnames: null }];
let output = [];
output = data.map(element => {
if (element.clienTnames) {
return element;
} else {
return { clienTnames: { firstName: '', lastName: '' } };
}
});
console.log(output);
let array = [{
clienTnames: {
firstName: 'Jack',
lastName: 'Jackson'
}
}, {
clienTnames: {
firstName: 'John',
lastName: 'Johnson'
}
}, {
clienTnames: null
}];
let targetArray;
targetArray = array.map((item) => {
if(!item.clienTnames) {
return { clienTnames: { firstName: '', lastName: '' } }
}
return item;
})

Categories