I would like to simplify a code snippet where I have one main loop in which I put 2 if statements. The first if statement is about a test "if (test1 or test2)" and the second one is a test "if (test1 and test2)".
Curently, to differentiate them, I have to put at a higher level (but still in the main loop) another "if" (test on diagExpression boolean, see below); here's the code :
// Main loop
while (Hit.arrayCurrent[Hit.coordCurrent[0]+k][Hit.coordCurrent[1]+l] == Hit.currentPlayer[1])
{
if (diagExpression)
{
if ((a > b) || (b > c))
return;
else if (d)
{
//do stuff1
}
}
else
{
if ((a > b) && (b > c))
return;
else if (d)
{
//do stuff1
}
}
}
I don't know how to do for simplifying this code snippet and avoiding to use the stuff1 2 times.
If anyone could see a solution.
UPDATE :
diagExpression is computed before the main loop :
// Boolean for 2 versions
var diagExpression = false;
if (Hit.direction == 'rightbottom')
{
diagExpression = true;
shift_x = 1;
shift_y = 1;
factor_x = 1;
factor_y = 1;
limit_x = 7;
limit_y = 7;
}
else if (Hit.direction == 'left')
{
shift_x = -1;
shift_y = 0;
factor_x = -1;
factor_y = 1;
limit_x = 0;
limit_y = -1;
}
...
// Main loop
while (Hit.arrayCurrent[Hit.coordCurrent[0]+k][Hit.coordCurrent[1]+l] == Hit.currentPlayer[1])
I use different directions values into my code and this boolean is true if I have diagonal directions and false for vertical/horizontal directions.
First you could simplify your code so that you'd need to write the stuff1 only once:
while (…) {
if (diagExpression) {
if ((a > b) || (b > c))
return;
} else {
if ((a > b) && (b > c))
return;
}
if (d) {
// do stuff1
}
}
or even
while (…) {
if (diagExpression ? (a > b) || (b > c) : (a > b) && (b > c)) {
return;
} else if (d) {
// do stuff1
}
}
and then you can get to the more advanced stuff, like
while (…) {
if ((a > b) + (b > c) >= 2 - diagExpression) {
return;
} else if (d) {
// do stuff1
}
}
though that gets rather unreadable, and might even be slower.
You can use this way :
if (diagExpression) {
if ((a > b) || (b > c))
return;
if ((a > b) && (b > c))
return;
}
if (d){
//do stuff1
}
This is what I believe #Daniel Daranas means as well.
Related
const [counter, setCounter] = useState(0);
function sortPeople() {
const sortedPeople = [...peopleList];
let sortCount = counter;
if (sortCount === 2) {
sortCount = 1;
setCounter(1);
} else {
sortCount += 1;
setCounter(sortCount);
}
if (sortCount < 3) {
sortedPeople.sort(function (x, y) {
if (sortCount === 1) {
return x.eaten === y.eaten
? 0
: x.eaten === "No"
? -1
: 1;
} else if (sortCount === 2) {
return x.eaten === y.eaten
? 0
: x.eaten === "No"
? 1
: -1;
}
});
setPeopleList(sortedPeople);
}
}
const [counterCount, setCounterCount] = useState(0);
function sortCountPeople() {
const sortedCountPeople = [...customerList];
let sortCountVisit = counterCount;
if (sortCountVisit === 2) {
sortCountVisit = 1;
setCounterCount(1);
} else {
sortCountVisit += 1;
setCounterCount(sortCountVisit);
}
sortedCountPeople.sort(function (x, y) {
if (sortCountVisit === 1) {
return x.number - y.number;
} else if (sortCountVisit === 2) {
return y.number - x.number;
}
});
setPeopleList(sortedCountPeople);
}
I have trouble understanding : the sort logic from the if sort count is < 3, then theres like ? : 0 -1 1 and also for sorting count theres like y-x and x-y so can someone explain this code to mean that would be great thank you in advance very much
!
Snippet 1
if (sortCount < 3) {
sortedPeople.sort(function (x, y) {
if (sortCount === 1) {
return x.eaten === y.eaten
? 0
: x.eaten === "No"
? -1
: 1;
} else if (sortCount === 2) {
return x.eaten === y.eaten
? 0
: x.eaten === "No"
? 1
: -1;
}
});
}
If sortCount is 0(?), 1, or 2 (i.e. less than 3) then the sortedPeople array will be sorted.
Using a compare function:
function compare(a, b) {
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
In other words, if -1 is returned then a comes before b and should move forward in the array, if 1 is returned then a comes after b and should move back in the array, and if 0 is returned a and b are considered "equal" and a stays where it's at.
In your callback if x.eaten is equal to y.eaten then 0 is returned and x doesn't move. If sortCount equals 1 and x isn't eaten yet then -1 is returned and x moves back in the array, otherwise it moves forward. If sortCount equals 2 then this is reversed, if x isn't eaten yet then 1 is returned and it moves forward, otherwise it moves back.
Update
Since there seems to be confusion over the ternary syntax I'll rewrite it using if-else statements.
function (x, y) {
if (sortCount === 1) {
if (x.eaten === y.eaten) {
return 0;
} else if (x.eaten === "No") {
return -1;
} else {
return 1;
}
} else if (sortCount === 2) {
if (x.eaten === y.eaten) {
return 0;
} else if (x.eaten === "No") {
return 1;
} else {
return -1;
}
}
}
Snippet 2
sortedCountPeople.sort(function (x, y) {
if (sortCountVisit === 1) {
return x.number - y.number;
} else if (sortCountVisit === 2) {
return y.number - x.number;
}
});
When comparing numbers the compare function can be much simpler:
function compareNumbers(a, b) {
return a - b;
}
If the result is negative, or less than zero, then a comes before b and should move forward in the array, if the result is positive, or greater than zero, then a comes after b and should move back in the array, and if the result is 0 they were equal and a stays where it's at.
In the callback if sortCountVisit equals 1 then the result will move x forward if it is less than y and back if it is greater than y. If sortCountVisit equals 2 then this is reversed, x moves back if less than y and forward if greater than y.
Doing a survey where a user picks :
A B or C
I then need to know if the user has picked Mostly A's, B's or C's.
I'm trying a few jQuery logics' but not having much luck, Due to expression expected error.
Is there a neater / better way to show purely which variable is the highest?
My current jQuery :
var count = 0;
var count_a = 0;
var count_b = 0;
var count_c = 0;
$('.radio-select').click(function()
{
var chosen_option = $(this).val();
if(chosen_option == 'a')
{
count++;
count_a ++;
}
if(chosen_option == 'b')
{
count++;
count_b ++;
}
if(chosen_option == 'c')
{
count++;
count_c ++;
}
check_numbers(count, count_a, count_b, count_c);
})
function check_numbers(count, a, b, c)
{
parseInt(a);
parseInt(b);
parseInt(c);
if(count == '8')
{
if ((a > b ) && (a > c))
{
alert("A is Highest");
}
if ((b > a ) && (b > c))
{
alert("B is Highest");
}
if(c > b) && (c > a))
{
alert("C is highest!");
}
}
}
jsFiddle Example
If you wanted a smaller way of doing it you could use inline if statements. Up to you if this is a better way, I like it though.
a = 5
b = 11
c = 6
console.log((a > b && a > c? a : (b > c ? b : c)))
Firstly you do not need to use parseInt() on a, b, c as they are already integers. And again count is an integer while you are comparing it to a string. This should work.
if(count == 8)
{
if ((a > b ) && (a > c))
{
alert("A is Highest");
}
else if ((b > a ) && (b > c))
{
alert("B is Highest");
}
else
{
alert("C is highest!");
}
You need to fetch the value returned by parseInt. Use it like: a = parseInt(a); and same for the other variables before comparing them in the if...else.
function check_numbers(count, a, b, c)
{
var x = parseInt(a),
y = parseInt(b),
z = parseInt(c);
if(count == 8)
{
var result = (x > y ? (x > z ? x : z) : (y > z ? y : z));
}
}
#StuBlackett you can consider adding the values and labels to an array then sorting Descending and returning the lable at the top.
function CompareIndexZero(a, b) {
if (a[0] < b[0]) return 1;
if (a[0] > b[0]) return -1;
return 0;
}
function myFunction() {
var count_a = 2;
var count_b = 5;
var count_c = 4;
var arrHighest = [];
arrHighest.push([count_a, "A"]);
arrHighest.push([count_b, "B"]);
arrHighest.push([count_c, "C"]);
arrHighest.sort(CompareIndexZero);
alert(arrHighest[0][1] + " is the highest");
}
Here is a modified version of check_numbers() that works as intended if I got you right. The point I want to make is the use of Math.max() to find the highest number from a selection of numbers.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
function check_numbers(count, a, b, c) {
if(count === 8) {
var numArray = [a, b, c];
var highest = Math.max.apply(null, numArray);
console.log(highest);
if (highest === a) {
console.log('a is highest');
} else if (highest === b) {
console.log('b is highest');
} else if (highest === c) {
console.log('c is highest');
}
}
}
check_numbers(8, 1 , 2, 5);
check_numbers(8, 5, 2, 1);
check_numbers(8, 1 , 5, 2);
Have you also taken into account that multiple answers could share the highest count?
My 2 cents on that:
var count = count_a = count_b = count_c = 0;
$('.radio-select').on('click', function() {
var chosen_option = $(this).val();
if (chosen_option == 'a') {
count_a++;
}
else if (chosen_option == 'b') {
count_b++;
}
else if (chosen_option == 'c') {
count_c++;
}
if (++count == 8) {
check_numbers(count_a, count_b, count_c);
}
});
function check_numbers(a, b, c) {
var highest = ((a > b && a > c) ? a : (b > c)? b : c),
multiple = false,
alertText = '';
if (a == highest) {
alertText += 'A';
}
if (b == highest) {
if (alertText != '') {
multiple = true;
alertText += ' and ';
}
alertText += 'B';
}
if (c == highest) {
if (alertText != '') {
multiple = true;
alertText += ' and ';
}
alertText += 'C';
}
alert(alertText + ' ' + (multiple ? 'are' : 'is') + ' highest!');
}
running lint on a test module is stating an error :
module.exports = (x) => {
if (x % 2 === 0) {
return 'even';
} else if (x % 2 === 1) {
return 'odd';
} else if (x > 100) {
return 'big';
} else if (x < 0) {
return 'negative';
}
};
running ESLint :
> yarn lint
../server/modules/my-awesome-module.js (1/0)
✖ 3:22 Expected to return a value at the end of this function consistent-return
✖ 1 error (7:35:56 PM)
error Command failed with exit code 1.
what is the correct ES6 coding in this case ?
thanks for feedback
You don't have an else case. If none of your if or else if conditions are met, there is no return value.
You could easily add a default else block or just a simple return at the end of the function.
The problem is that based on some code paths (any of the if/else clauses), a value might be returned by the function. however, in cases where none of the cases match (for example, where x=50.5), nothing is returned. For consistency purposes, something should be returned by the function.
An example solution would be:
module.exports = (x) => {
if (x % 2 === 0) {
return 'even';
} else if (x % 2 === 1) {
return 'odd';
} else if (x > 100) {
return 'big';
} else if (x < 0) {
return 'negative';
}
return 'none'
};
You can consider changing the code snippet as
module.exports = (x) => {
var result = "";
if (x % 2 === 0) {
result = "even";
} else if (x % 2 === 1) {
result = "odd";
} else if (x > 100) {
result = "big";
} else if (x < 0) {
result = "negative";
}
return result;
};
Hope it helps
I am using jquery datatable to display data. I display '--' when there is no data. Currently when the table sorts the data all the '--' comes in the beginning and the order looks like below:
--
--
10
20
400
800
But I need to make '--' to be displayed last when sorted in ascending order and should look something like below:
10
20
400
800
--
--
Please let me know how can we get this behavior in jquery datatable?
you can use an exstension
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
"myorder-pre": function (a) {
},
"myorder-asc": function (a, b) {
if(a == '--' && b != '--')
return 1;
else if(b == '--' && a != '--')
return -1;
else if(b == '--'&& a == '--')
return 0;
else
{
a = parseFloat(a);
b = parseFloat(b);
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}
},
"myorder-desc": function (a, b) {
if(a == '--' && b != '--')
return -1;
else if(b == '--' && a != '--')
return 1;
else if(b == '--'&& a == '--')
return 0;
else
{
a = parseFloat(a);
b = parseFloat(b);
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
}
});
myorder-pre is used before all the order call.
myorder-asc when you order asc. Return number negative if a minor b, positive if a major b, 0 if equal.
Desc work adverse
then in the definition of columns of datatable, use
"aoColumnDefs": [{ "sType": 'myorder'}]
You can make use of the following code :
$('#example').dataTable( {
"aaSorting": [[ 4, "desc" ]]
} );
For the reference
I'm sorting an object array that has a primary contact name, among other things. Sometimes this has a blank value and when I use the function below it sorts it all correctly, but all the blanks go at the top of the list instead of the bottom. I thought that adding the condition shown below would work, but it does not.
this.comparePrimaryContactName = function (a, b)
{
if(a.PrimaryContactName == "") return -1;
return a.PrimaryContactName > b.PrimaryContactName ? 1 : -1;
}
What am I missing?
I usually use something like this:
this.comparePrimaryContactName = function(a, b) {
a = a.PrimaryContactName || '';
b = b.PrimaryContactName || '';
if(a.length == 0 && b.length == 0)
return 0;
else if(a.length == 0)
return 1;
else if(b.length == 0)
return -1;
else if(a > b)
return 1;
else if(a < b)
return -1;
return 0;
}
Comparison functions must be reflective, transitive, and anti-symmetric. Your function does not satisfy these criteria. For example, if two blank entries are compared with each other, you must return 0, not -1.
this.comparePrimaryContactName = function (a, b)
{
var aName = a.PrimaryContactName;
var bName = b.PrimaryContactName;
return aName === bName ? 0 :
aName.length===0 ? -1 :
bName.length===0 ? 1 :
aName > bName ? 1 : -1;
}
Return 1 instead of -1 for blanks.
this.comparePrimaryContactName = function (a, b) {
if (a.PrimaryContactName == b.PrimaryContactName)
return 0;
if(a.PrimaryContactName == "") return 1;
return a.PrimaryContactName > b.PrimaryContactName ? 1 : -1;
}
Your sort function should return 0 if the two are equal, -1 if a comes before b, and 1 if a comes after b.
See the MDN sort doco for more information.