Filter, Closure, Functional Syntax Version of for Loop with Multiple Conditions

Filter, Closure, Functional syntax version of for loop with multiple conditions

If you want the first element of the array that satisfies the criteria
use this.

if let voiceToUse = AVSpeechSynthesisVoice.speechVoices().first(where: {
$0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
}){

//use the voiceTouse Variable

}

If you want the last of the element of the array that satisfies the
criteria use this.

if let voiceToUse = AVSpeechSynthesisVoice.speechVoices().reversed().first(where: {
$0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
}){

//use the voiceTouse Variable

}

yes sure, we can use guard let ...

A guard statement is used to transfer program control out of a scope if one or more conditions aren’t met.
in this example, if the condition is not met, ie there is no element in AVSpeechSynthesisVoice.speechVoices() that meet the criteria, guard let will transfer the program control out of the check function ,else if there is the some element in AVSpeechSynthesisVoice.speechVoices() that meet the criteria, program control goes to the next line after the guard let statement

func check(){
guard let voiceToUse = AVSpeechSynthesisVoice.speechVoices().first(where: {
$0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
})else{
return
}
//use the voiceToUseVariable

}

check()

Numpy where function multiple conditions

The best way in your particular case would just be to change your two criteria to one criterion:

dists[abs(dists - r - dr/2.) <= dr/2.]

It only creates one boolean array, and in my opinion is easier to read because it says, is dist within a dr or r? (Though I'd redefine r to be the center of your region of interest instead of the beginning, so r = r + dr/2.) But that doesn't answer your question.


The answer to your question:
You don't actually need where if you're just trying to filter out the elements of dists that don't fit your criteria:

dists[(dists >= r) & (dists <= r+dr)]

Because the & will give you an elementwise and (the parentheses are necessary).

Or, if you do want to use where for some reason, you can do:

 dists[(np.where((dists >= r) & (dists <= r + dr)))]

Why:
The reason it doesn't work is because np.where returns a list of indices, not a boolean array. You're trying to get and between two lists of numbers, which of course doesn't have the True/False values that you expect. If a and b are both True values, then a and b returns b. So saying something like [0,1,2] and [2,3,4] will just give you [2,3,4]. Here it is in action:

In [230]: dists = np.arange(0,10,.5)
In [231]: r = 5
In [232]: dr = 1

In [233]: np.where(dists >= r)
Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),)

In [234]: np.where(dists <= r+dr)
Out[234]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),)

In [235]: np.where(dists >= r) and np.where(dists <= r+dr)
Out[235]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),)

What you were expecting to compare was simply the boolean array, for example

In [236]: dists >= r
Out[236]:
array([False, False, False, False, False, False, False, False, False,
False, True, True, True, True, True, True, True, True,
True, True], dtype=bool)

In [237]: dists <= r + dr
Out[237]:
array([ True, True, True, True, True, True, True, True, True,
True, True, True, True, False, False, False, False, False,
False, False], dtype=bool)

In [238]: (dists >= r) & (dists <= r + dr)
Out[238]:
array([False, False, False, False, False, False, False, False, False,
False, True, True, True, False, False, False, False, False,
False, False], dtype=bool)

Now you can call np.where on the combined boolean array:

In [239]: np.where((dists >= r) & (dists <= r + dr))
Out[239]: (array([10, 11, 12]),)

In [240]: dists[np.where((dists >= r) & (dists <= r + dr))]
Out[240]: array([ 5. , 5.5, 6. ])

Or simply index the original array with the boolean array using fancy indexing

In [241]: dists[(dists >= r) & (dists <= r + dr)]
Out[241]: array([ 5. , 5.5, 6. ])

Numpy where with multiple conditions

You can use a ternary:

np.where(consumption_energy > 400, 'high', 
(np.where(consumption_energy < 200, 'low', 'medium')))

Where-Object multiple conditions not working

Where-Object { "status" -eq "inProgress" -and "templateParameters.param1" -eq "myparam" }

You're comparing (distinct) string literals to each other, whereas you presumably mean to compare property values to string literals.

You need the automatic $_ variable to refer to the pipeline input object at hand inside a script block ({ ... }), which allows you to access its properties:

Where-Object { 
$_.status -eq "inProgress" -and $_.templateParameters.param1 -eq "myparam"
}

Note that Where-Object (and also ForEach-Object) alternatively supports simplified syntax, where you don't need a script block and where the use of $_ is implied, but this syntax is limited to:

  • a single conditional

  • non-nested property access.

Therefore, its use is not an option in your case.

Only the first -eq comparison, with its access to the immediate status property only could be expressed in simple syntax (as you show in your question):

# Equivalent of:
# Where-Object { $_.status -eq 'inProgress' }
# 'status' binds positionally to the -Property parameter.
Where-Object status -eq 'inProgress'

By contrast, the nested property access would not work:

# !! Does NOT work as intended.
Where-Object templateParameters.param1 -eq 'myparam'

The reason is that templateParameters.param1, which positionally binds to the -Property parameter, is as a whole interpreted as the name of a single property.

While chaining multiple simple-syntax Where-Object calls may be worth it for syntactic convenience, in your case you'd have to chain a simple-syntax with a regular-syntax call, in which case you may as well stick with your original, single regular-syntax approach.

PySpark: multiple conditions in when clause

You get SyntaxError error exception because Python has no && operator. It has and and & where the latter one is the correct choice to create boolean expressions on Column (| for a logical disjunction and ~ for logical negation).

Condition you created is also invalid because it doesn't consider operator precedence. & in Python has a higher precedence than == so expression has to be parenthesized.

(col("Age") == "") & (col("Survived") == "0")
## Column<b'((Age = ) AND (Survived = 0))'>

On a side note when function is equivalent to case expression not WHEN clause. Still the same rules apply. Conjunction:

df.where((col("foo") > 0) & (col("bar") < 0))

Disjunction:

df.where((col("foo") > 0) | (col("bar") < 0))

You can of course define conditions separately to avoid brackets:

cond1 = col("Age") == "" 
cond2 = col("Survived") == "0"

cond1 & cond2

Loop to remove an element in array with multiple occurrences

You have a built in function called filter that filters an array based on a predicate (a condition).

It doesn't alter the original array but returns a new filtered one.

var array=["hello","hello","world",1,"world"];
var filtered = array.filter(function(element) {
return element !== "hello";
}); // filtered contains no occurrences of hello

You can extract it to a function:

function without(array, what){
return array.filter(function(element){
return element !== what;
});
}

However, the original filter seems expressive enough.

Here is a link to its documentation

Your original function has a few issues:

  • It iterates the array using a for... in loop which has no guarantee on the iteration order. Also, don't use it to iterate through arrays - prefer a normal for... loop or a .forEach
  • You're iterating an array with an off-by-one error so you're skipping on the next item since you're both removing the element and progressing the array.

Filter column on multiple criteria and copy to different sheet

You can use array.includes() to check if the current row column e value is listed in your filterValues for your array filter function.

Sample code:

function myFunction() {
var filterValues = ["Money", "Society"]; //filter values.
var col = 5; // column "E".
var sheetName = "Elements";

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sht = ss.getSheetByName(sheetName);
var rng = sht.getDataRange();
var rawData = rng.getDisplayValues();

var out = rawData.filter(dataFilter);

function dataFilter(arr) {
return filterValues.includes(arr[col-1]);
}
Logger.log(out);
const osh=SpreadsheetApp.getActive().getSheetByName("A");
osh.clear();
osh.getRange(1,1,out.length,out[0].length).setValues(out);
};

What it does?

  1. Get the data range values
  2. Filter the 2-d array values if column E value was found in your filterValues array.
  3. Write the filtered array on the destination sheet.

Output:

Source Sheet: Elements

Sample Image

Destination Sheet: A

Sample Image

Way to loop over multiple tables and keep only if condition met?

This sounds like a problem for the dplyr package, which. The dplyr package allows you to string together data operations in a "pipe" to avoid storing things in memory. The pipe operator %>%takes the output of the function on the left and uses it as the first argument of the function on the right. Each function in the dplyr package works over the entire vector or data tibble, so no need for loops.

So, your operation might look like the following:

# Initialize random data like your first table
df1 <- data.frame(product = sample(LETTERS[1:10], 10000, replace = TRUE),
date1 = sample(seq(as.Date("2020/08/01"), as.Date("2020/08/31"),
by = "day"), 10000, replace = TRUE),
cost = round(runif(10000, 5, 100)))
# Initialize random data like your second table
df2 <- data.frame(product = sample(LETTERS[1:10], 10000, replace = TRUE),
date2 = sample(seq(as.Date("2020/09/01"), as.Date("2020/09/30"),
by = "day"), 10000, replace = TRUE),
price = round(runif(10000, 5, 100)))
# Initialize discounts
discounts <- data.frame(product = rep(LETTERS[1:10],4),
discount = rep(c(0, 0.1, 0.12, 0.18), 10))
library(dplyr)
out_table <- df1 %>%
full_join(df2) %>%
full_join(discounts) %>%
mutate(profit = price * discount - cost) %>%
filter(profit > 0)

For my random data, this takes about 3 seconds on my machine. Furthermore, the filter verb only keeps those rows we want.

How to filter an array by a condition

$fullArray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);

function filterArray($value){
return ($value == 2);
}

$filteredArray = array_filter($fullArray, 'filterArray');

foreach($filteredArray as $k => $v){
echo "$k = $v";
}


Related Topics



Leave a reply



Submit