Find if value is undefined of multiple keys in object - javascript

I would like to detect if some values are not defined in an object with several properties
for example :
let test = {
helo: undefined,
hey: "not undefined"
}
i tried this :
const object1 = {
a: 'somestring',
b: 42
};
for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
but if possible, I don't want to use a for loop, I would like a boolean result in return

You could be looking for something like this.
const test = {
helo: undefined,
hey: "not undefined"
};
const some_undefined = Object.values(test).some(v => v === undefined);
console.log(some_undefined);

You can use a function for that :
const hasOneKeyUndefined = (object)=>
{
for (const [key, value] of Object.entries(object)) {
if (value === undefined) return true;
}
return false;
}

You could also use Object.keys
const test = {
helo: undefined,
hey: "not undefined"
};
Object.keys(test).map((key, idx) => test[key] === undefined)

Related

How to get values from array of objects in javascript

I have an array of object from which I am trying to get values using map operator but I am getting the whole json objects all I want is just array of values.
Below is my code:
const obj = [
{
a: {
b: 'Paul',
}
},
{
c: 'Byeeee',
}
];
obj.map((val) => console.log(val));
what I am getting is
{ a: { b: 'Paul' } }
{ c: 'Byeeee' }
What I want is:
['Paul','Byeeee']
Someone let me know how can I get the desired output.
You can do this recursively. You can first start off by grabbing the values of your object, and then loop through those using .flatMap(). If you encounter a value that is an object, you can recursively grab the values of that object by recalling your function. Otherwise, you can return the value. The advantage of using .flatMap() here is that when the recursive call returns an array, we don't end up with inner arrays, but rather the array gets flattened into one resulting array:
const obj = [{ a: { b: 'Paul', } }, { c: 'Byeeee', } ];
const getValues = (obj) => {
return Object.values(obj).flatMap(val => Object(val) === val ? getValues(val) : val);
}
console.log(getValues(obj));
you can use the following solution.
const data = [{ a: { b: 'Paul' } }, { c: 'Byeeee' }];
const flatObjectValues = (obj, result) => {
// recursive function to get object values
const objValues = Object.values(obj);
if (objValues?.length > 0) {
objValues.map((v) => {
if (typeof v === 'object' && !Array.isArray(v)) {
flatObjectValues(v, result);
} else {
result.push(v);
}
return v;
});
}
};
const updatedData = [];
data.map((x) => flatObjectValues(x, updatedData));
console.log('updatedData: ', updatedData);
You can use recursion with array.reduce, like fellowing.
function getAllValues(objuct) {
return objuct.reduce((acc, curr) => {
if (typeof curr === 'object') {
return [...acc, ...getAllValues(Object.values(curr))];
}
return [...acc, curr];
}, []);
}
A recursive solution could be:
const arr = [{a: {b: "Paul",},},{c: "Byeeee",},];
const flatArrOfObjects = (arr) => {
const values = [];
for (const i in arr) flatObj(arr[i], values);
return values;
};
const flatObj = (obj, result) => {
for (const [key, value] of Object.entries(obj)) {
if (typeof value === "object") flatObj(value, result);
else result.push(value);
}
};
console.log(flatArrOfObjects(arr));

Copy properties of object to another skipping undefined ones

How can I copy a list of properties from a object to another skipping the null or undefined values?
Something like this
const obj1 = { prop1: 'value', prop2: undefined }
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3']) // prop3 doesn't exist and prop2 should be excluded
console.log(obj2) // should print { prop1: 'value' }
Here using Object.fromEntries() and Array.prototype.filter().
see: Object.fromEntries(): Object transformations
const obj1 = { prop1: 'value', prop2: undefined }
const copy = (obj, props) => {
return Object.fromEntries(Object.entries(obj)
.filter(([k, v]) => (
(props.includes(k) && v !== undefined && v !== null)
)));
}
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3'])
console.log(obj2)
Try this:
const obj1 = { prop1: 'value', prop2: undefined }
function copy(obj1, props)
{
return props.reduce(
(acum, current) =>
(obj1[current] !== undefined && obj1[current] !== null) ?
({...acum, [current]:obj1[current]}):
acum
,{}
)
}
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3']) // prop3 doesn't exist and prop2 should be excluded
console.log(obj2) // should print { prop1: 'value' }
function copy(object, keys) {
const clone = {};
for(const key of keys) {
if(!isNaN(object[key])) clone[key] = object[key];
}
return clone;
}
It's not clear what the purpose of the array is in your code, but this should work for the problem as you stated it. It reduces over the entries of the original object with a new object as an accumulator, and only copies over properties with defined values. To include null in the check, you can change the condition to be != null (because undefined == null).
const copyExcludingUndefined = (obj = {}) =>
Object.entries(obj)
.reduce((a, [k, v]) => {
if (v !== undefined) {
a[k] = v
}
return a
}, {})
Write your own copy function :)
let copy = function(o, args) {
let obj = {};
if (Array.isArray(args)) {
args.forEach(arg => {
if(o[arg] !== undefined) {
obj[arg] = o[arg];
}
});
}
return obj;
}

Get the length of the values in object

I want to get the length of values from an object. If the value has no length i should get 0 length, if value exists i should get value.
const object1 = {
a: '',
b: '5'
};
function app() {
for (const [key, value] of Object.entries(object1)) {
console.log(key, value)
return {
[key]: !object1[key].length ? '0 length' : value
}
}
}
console.log(app())
Question:
Why i get just first value from object?
{
"a": "0 length"
}
expect:
{
"a": "0 length",
"b": 1
}
Why now i get in console.log(key, value) just the first value-key, but if i delete the return statement i get both value-key?
const object1 = {
a: '',
b: '5'
};
function app() {
for (const [key, value] of Object.entries(object1)) {
console.log(key, value)
// return {
// [key] : !object1[key].length ? '0 length' : value
// }
}
}
console.log(app())
Because you are returning from very first value inside for you are getting only one value in result.
Instead of that take one variable for ex let result = {}; Assign length values to it inside for as result[key] = value.toString().length || '0 length'; and then return result;.
Try it below.
const object1 = {
a: '',
b: '5'
};
function app() {
let result = {};
for (const [key, value] of Object.entries(object1)) {
// console.log(key, value)
result[key] = value.toString().length || '0 length';
}
return result;
}
console.log(app());
If your expected output is array then use like below. For array result you can also use map with like shown in app2.
const object1 = {
a: '',
b: '5'
};
function app() {
let result = [];
for (const [key, value] of Object.entries(object1)) {
result.push({[key]: value.toString().length || '0 length'});
}
return result;
}
function app2() {
return Object.entries(object1).map(([key, value]) => ({[key]: value.toString().length || '0 length'}));
}
console.log(app());
console.log(app2());
return exits the loop after first iteration
Perhaps you should do something like this
const object1 = {
a: '',
b: '5'
};
const newObj = {};
function app() {
for (const [key, value] of Object.entries(object1)) {
console.log(key, value)
newObj[key] = !object1[key].length ? '0 length' : value
}
return newObj;
}
console.log(app())
const object1 = {
a: '',
b: '5'
};
function app() {
const result = [];
for(let key in object1) {
if(object1[key] && object1[key].length) {
result.push({[key] :`${object1[key].length} length`});
} else {
result.push({[key] :`0 length`});
}
}
return result;
}
console.log(app())

Lodash findKey() method

As a part of a challenge I need to implement the .findKey() method myself. Below is the solution proposition, however, I get an error "predicate is not a function".
const _ = {
findKey(object, predicate) {
for (let key in object) {
let value = object[key];
let predicateReturnValue = predicate(value);
if (predicateReturnValue) {
return key;
};
};
undefined
return undefined;
}
};
Can anyone help?
function findKey(object, predicate) {
for (let key in object) {
let value = object[key];
let predicateReturnValue = predicate(value);
if (predicateReturnValue) { // just take the value
return key; // return key
}
}
}
const isEqual = a => b => a === b
const object = { a: 'Apple', b: 'Beer', c: 'Cake' }
alert(findKey(object, isEqual('Apple')));
alert(findKey(object, isEqual('Cakes')));

Trimming all values in object; Error: Cannot set property of undefined

I'm receiving this object from an API:
{
"id": 10,
"lectura": "zx71 ",
"articulo": "ZX71 ",
"ubicacion": "ddd ",
"uds": 5,
"usuario": null,
"createD_AT": "2019-12-04T08:19:56.12"
}
I want to trim the values so I have this function:
const trimValues = object => {
console.log(JSON.stringify(object, null, 2))
const trimmedProperties = Object.entries(object).reduce(
(acc, [key, value]) => {
if (typeof value == "string") {
return (acc[key] = value.trim());
}
},
{}
);
return { ...object, trimmedProperties };
};
The problem is that I'm getting this error message:
core.js:9110 ERROR TypeError: Cannot set property 'lectura' of undefined
The error is returned in this line: return (acc[key] = value.trim());
What am I missing?
There are 3 main mistakes first one is that in case of value not being a string you did not return anything meaning that the next iteration of the reduce would receive acc===undefined, and second being that return of the assignment call will just return the value of the key instead of entire object, last being that you also have to destructurize the trimmer properties, you can fix it by doing the following
const trimValues = object => {
console.log(JSON.stringify(object, null, 2))
const trimmedProperties = Object.entries(object).reduce(
(acc, [key, value]) => {
if (typeof value == "string") {
acc[key] = value.trim();
}
return acc
},
{}
);
return { ...object, ...trimmedProperties };
};
however there really isn't a reason you should combine the untrimmed properties (not strings) with trimmed ones only after iterating over it, instead to simplify it and remove unnecessary iterations you could do the following:
const trimValues = object => {
console.log(JSON.stringify(object, null, 2))
return Object.entries(object).reduce((acc, [key, value]) => {
acc[key] = (typeof value === "string") ? value.trim() : value;
return acc
}, {});
};

Categories

Resources