Using if-else statement in a block [] - javascript

I have the following statement:
arr.push([student.name,student.id]);
I want to add an if-else block in this statement so I could add student.name only if the if is true, something like:
arr.push([student.name if (validName(student.name))
,student.id]);
But this syntax is not valid. Is there a proper way to achieve this idea?
EDIT:
My array contains a lot of elements and I want to add to most of them (if not all of them) some kind of check. Something like:
arr.push([student.name if (validName(student.name)),
student.id if (validId(student.id) && idContainsNine(student.id)),
student.avg if (student.avg !== 'undefined'),
...
]);
I push the values only if the if statement is true. If it false, it will not push it. for example if validName(student.name) returns false it will not push student.name in the array.

You could take a conditional operator and get only an array with valid values.
array.push(validName(student.name)
? [student.name, student.id]
: [student.id]
);
An other approach is to use functions which return after a check either an array with the value or without.
For using this result, you need to spread the array and if it does not contain any element, it does not increase the length of the array.
cost
includeName = name => validName(name) ? [name] : [],
includeId = id => validId(id) && idContainsNine(id) ? [id] : [],
includeAVG = avg => avg !== 'undefined' ? [avg] : [];
arr.push([
...includeName(student.name),
...includeId(student.id),
...includeAVG(student.avg)
]);
Another solution could be to use an array of checks and return in case of unwanted items an own Symbol (if undefined or ``null` is a used value) and filter the array before pushing it to the result set.
const
EMPTY = new Symbol('empty'),
checkName = ({ name }) => validName(name) ? name : EMPTY,
checkId = ({ id }) => validId(id) && idContainsNine(id) ? id : EMPTY,
checkAVG = ({ avg }) => avg !== 'undefined' ? avg : EMPTY;
array.push([checkName, checkId, checkAVG]
.map(fn => fn(student))
.filter(v => v !== EMPTY)
);

Consider ternary operator.
arr.push([validName(student.name) ? student.name : '', student.id]);
Replace empty string value '' with what you want when you get invalid student.name.

Use this one.It may help you.
arr.push([student.name,(student.id ? student.id : '')]);

Related

Returning only a property of an element passed in to a forEach loop in JavaScript

let bloodGroup = bloodCodeArray.forEach(bloodCode => (bloodCode.code.toUpperCase() === bloodType.toUpperCase()) ? bloodCode.code : bloodType);
I expect this to return only a property of 'bloodCode' element (code) in my call back function of an angular code, but this is returning the entire element even though I'm selecting it in the ternary operator. Please explain.
let bloodGroup = bloodCodeArray.map(bloodCode => (bloodCode.code.toUpperCase() === bloodType.toUpperCase()) ? bloodCode.code : bloodType);
As per your requirement, You have to use Array.map() method which returns a new array by applying the callback function on each element of an array.
Live Demo :
const bloodCodeArray = [{
code: 'A'
}, {
code: 'o'
}, {
code: 'b'
}, {
code: 'O+'
}];
const bloodType = 'O';
let bloodGroup = bloodCodeArray.map(bloodCode => (bloodCode.code.toUpperCase() === bloodType.toUpperCase()) ? bloodCode.code : bloodType);
console.log(bloodGroup);
let bloodGroup = bloodCodeArray
.filter(bc => (bc.code.toUpperCase() === bloodType.toUpperCase()) ? bc.code : bloodType)
.map(bg=>bg.code)
.pop()
I was able to resolve this by using this code does anyone has a shorter or prettier way of doing the same?
After going through the comments on the question I realized using forEach will not work as it only returns undefined.

How can I filter the result of a ternary that's inside a map?

I'm 100000% new to the ternary world, so I really don't understand what's going on. I have the following:
categories.forEach((category) => {
const errorCategory = {
[category]: response.map(
(r) => r.ds_category === category && r.ds_name
),
};
errors = { ...errors, ...errorCategory };
});
I want to filter the r.ds_name to remove all "false" results, how could I do this? I tried:
Doing the filter straight away (r.ds_name.filter(blablabla)) but I get a "this is not a function" error.
Switching from ternary to the old school function, and didn't get any results either.
Filtering errorCategory (errorCategory = errorCategory.filter((item) => item === "false"), but I also got the "this is not a function" error.
Thanks :(
To filter an array, I'd recommend using '.filter' instead of '.map'. This will remove the elements which do not match the requirement set. Assuming response is an object which is an array, or other object which implements 'filter', you can do the following (note the extra brackets):
categories.forEach( ( category ) => {
const errorCategory = {
[ category ]: response.filter(
(r) => (r.ds_category === category && r.ds_name)
),
};
//Do stuff
}
You can use ternary operator in a filter method like this
const newArray = array.filter( element => {
element.property === "text" ? true : false
})
It check for element.property is equal to "text". If it is equal it returns true. If not returns false. But you dont need to do that. You can simply do this
const newArray = array.filter( element => {
element.property === "text"
})
This would return the same result

Conditially using an object property

I have the following ternary:
exceptionType == 'Asset' ? selection = selectedAssets.find(function(obj) {return obj.fixedTitle === element}) : selection = dedupedAssets.find(function(obj) {return obj.fixedTitle === element});
I am conditionally assigning the variable selection to the value returned by find(). The functions are extremely similar, with the only difference being the array that is targeted.
Is there a way I can shorten this even further?
You could use the ternary operator to know what items to be iterated on and use the logic run once instead of duplicating it.
const itemsToIterate = exceptionType == 'Asset' ? selectedAssets : dedupedAssets;
const items = itemsToIterate.find(function(obj) {return obj.fixedTitle === element});
You can tweak this a bit to make it even shorter.
const itemsToIterate = exceptionType == 'Asset' ? selectedAssets : dedupedAssets;
const items = itemsToIterate.find(({ fixedTitle }) => fixedTitle === element);
You can use your boolean condition as an index to get the right array to apply find to:
const selection = [dedupedAssets, selectedAssets][+(exceptionType === 'Asset')]
.find(o => o.fixedTitle === element);
Using the operator +, false will be converted to 0 and dedupedAssets will be returned, and true will be converted to 1 and selectedAssets will be returned.
Indexing example
const a = [{ title: 'hello' }];
const b = [{ title: 'world' }];
console.log([a, b][+false].find(o => o.title === 'hello'));
console.log([a, b][+true].find(o => o.title === 'world'));

JS .filter() works when intereger is passed in, but not when variable is passed in

I'm trying to use the .filter to pull an object out of an array of objects.
When I do this:
var homeCountry = this.props.searchedCountry.filter(country => country.id === 7);
I get a the filtered array, but when I do this:
var homeCountry = this.props.searchedCountry.filter(country => country.id === e.target.country.value);
where e.target.country.value === 7, I get an empty array.
Can anyone explain what's going on? Thanks!
e.target.value is string value. you are doing strict comparison with datatype and value.
Updated Code
var homeCountry = this.props.searchedCountry.filter(country => country.id === parseInt(e.target.country.value));
e.target.value will be a string, but they are several ways to handle this, is either you use parseInt(e.target.value) or Number(e.target.value) or e.target.valueAsNumber. And secondly === checks the value and also the data type of the operands you are comparing therefore ( 1 === "1" ) will be evaluated as false but ( 1 === 1 ) will be evaluated as true, doing == will only compare the values, if you want to use == (non strict equal to ) it is not necessary that you should use the above suggested solution to handle the issue therefore ( 1 == 1 ) is true and ( 1 == "1" ) is also true, but if you wish to use === (which is advisable) use the above suggested solution

JS one-liner filter similar objects from 2 arrays

I'm trying to filter 2 arrays that have similar objects.
genreFiltered returns correctly
sortFiltrered should return an aray with 5 objects like the recommended Array.
Instead it returns empty.
Can someone spot what i'm doing wrong with the way i'm filtering the 2 arrays in sortFiltrered?
let genreFiltered = genreValue !== 15 ? games.filter((game) => game.genre_id === genreValue) : games
let sortFiltrered= sortValue !== 1 ? genreFiltered.filter((game) => game.game_id === recommended.filter((rec) => rec.game_id)) : genreFiltered
console.log('recommended', recommended)
console.log('genreFiltered', genreFiltered)
console.log('sortFiltrered', sortFiltrered)
Output:
It can't be equal ... You should get at least the first element.
let ageFiltrered = sortValue !== 1 ? genreFiltered.filter((game) => game.game_id === recommended.filter((rec) => rec.game_id)[0].game_id)
That code will filter all those that have a game_id, and the it will check first ocurrence.
If you want to not only check the first occurence you can do something like that (it is just a simple example but you can use it in your case):
var arr = [{w:'2'}, {w:'3'}, {w:'12'}, {w:'456'}]
arr.filter(w => w.w.indexOf(arr.filter(w => w.w === '22').map(w => w.w).join()) !== -1)
well, in this part
genreFiltered.filter((game) => game.game_id === recommended.filter((rec) => rec.game_id))
game.game_id seems to be an integer and the result of recommended.filter((rec) is an array. So, they are not ===.
Maybe you could use == if you know that the result of recommended.filter((rec) => {...}) is an array with 1 element. Then it will be casted to a string like '1' and then with == operator it will be casted to an integer so that 1 == [1] will give you true.

Categories

Resources