Find indices of elements that match a given condition
Ruby 1.9:
arr = ['x', 'o', 'x', '.', '.', 'o', 'x']
p arr.each_index.select{|i| arr[i] == 'x'} # =>[0, 2, 6]
Code
Python: How to find indices of elements that satisfy conditions in each row, and transformed them to a dict?
np.unique
can be used with indexes to get both the dictionary keys and locations, then use np.split
to divide the array, then zip
together the keys and the arrays to build the dictionary from the tuples:
g0 = np.argwhere(myarray > 0)
keys, locs = np.unique(g0[:, 0], return_index=True)
d = dict(zip(keys, np.split(g0[:, 1], locs[1:])))
np.nonzero
may be faster than np.argwhere
in this case:
i, v = np.nonzero(myarray > 0)
keys, locs = np.unique(i, return_index=True)
d = dict(zip(keys, np.split(v, locs[1:])))
However, a simple dictionary comprehension is likely the fastest option on smaller arrays:
d = {i: np.nonzero(r > 0)[0] for i, r in enumerate(myarray)}
All options produce d
:
{0: array([0, 1, 3]),
1: array([0, 1, 2, 3]),
2: array([0]),
3: array([0, 1, 2]),
4: array([0, 1, 2])}
Setup and imports:
import numpy as np
np.random.seed(20211021)
myarray = np.random.randint(0, 5, size=(5, 4))
Find indices of elements that match condition of 2D array by row
Using np.where
+ np.split
x, y = np.where(A.T < B)
s = np.flatnonzero(np.append([False], x[1:] != x[:-1]))
np.split(y, s)
[array([0, 1, 2], dtype=int64),
array([1, 2], dtype=int64),
array([2], dtype=int64)]
Find indexes of array that match a condition, then push into another array
Matching Condition
This answer presumes that you're looking to get the indices of the elements which are of equal length to the element in the array with the maximum length.
Getting the Indices
To get the length of the longest element, we first get the lengths of each element, then reduce the array so as to get only the maximum length.
Next, we map each element of the array to one of two things; if the element is the same length as the maximum length, we take its index. If it isn't, then we map false
instead. We do that so we can filter out those values.
Lastly, we filter out values which are false. These values were not as long as the maximum length, so we don't want them.
As T.J.Crowder alluded to, a forEach
might do this in a way that's more direct, and potentially more readable. Experimenting with chaining array methods in this way will allow you to make a good decision as to the kind of code which will work best for the situation with which you are faced.
If you are working with very large data sets, then iterating over your data multiple times in order to improve code readability, at the expense of performance, is probably a bad idea.
const arr = ["00", "000", "", "0", "000"]
const maxLength = arr .map(e => e.length) .reduce((a, b) => a > b ? a : b) const result = arr .map((val, i) => val.length === maxLength ? i : false) // log the index of the item if the item's length is 1 .filter(i => i !== false) // remove non-truthy elements console.dir(result)
find first element and index matching condition in list
You could do it in a list comprehension. This is basically the same as your code but condensed into one line, and it builds a list of results that match the criteria.
The first way gets all the matches
mylist = [-1,-2,3,4,5,6]
results = [(i, el) for i, el in enumerate(mylist) if el > 0]
Another way would be to use a generator expression which is probably faster, and just unpack it. This gets the first one.
*next((i, el) for i, el in enumerate(mylist) if el > 0))
This loops the list and checks the condition, then puts the index and element into a tuple. Doing this inside parentheses turns it into a generator, which is much faster because it hasn't actually got to hold everything in memory, it just generates the responses as you need them. Using next()
you can iterate through them. As we only use next() once here it just generates the first match. Then we unpack it with *
As there are two other valid answers here I decided to use timeit module to time each of them and post the results. For clarity I also timed the OP's method. Here is what I found:
import timeit
# Method 1 Generator Expression
print(timeit.timeit('next((i, el) for i, el in enumerate([-1,-2,3,4,5,6]) if el > 0)', number=100000))
0.007089499999999999
# Method 2 Getting index of True
print(timeit.timeit('list(x > 0 for x in [-1,-2,3,4,5,6]).index(True)', number=100000))
0.008104599999999997
# Method 3 filter and lambda
print(timeit.timeit('myidx , myel = list(filter(lambda el: el[1] > 0, enumerate([-1,-2,3,4,5,6])))[0]', number=100000))
0.0155314
statement = """
for idx, el in enumerate([-1,-2,3,4,5,6]):
if el > 0:
myidx, myel = idx, el
break
"""
print(timeit.timeit(statement, number=100000))
0.04074070000000002
Get all the indexes from the array on matching the condition
You don't need to convert the array to List to do this operation, all you can do is:
int[] indexes = IntStream.range(0, updateResultArray.length)
.filter(i -> updateResultArray[i] > 0)
.toArray();
get indexes with condition
You can use enumerate in a conditional list comprehension to get the index locations.
my_list = [5, 8, 2, 7, 8, 8, 2, 4]
search_value = 8
>>> [i for i, n in enumerate(my_list) if n == search_value]
[1, 4, 5]
If the search value is not in the list, then an empty list will be returned (not exactly None, but still a falsey).
Using pandas, you can use boolean indexing to get the matches, then extract the index to a list:
df[df[0] == search_value].index.tolist()
Using an empty list will satisfy the condition for None (they both evaluate to False). If you really need None, then use the suggestion of @cᴏʟᴅsᴘᴇᴇᴅ.
How to find the indices of all elements matching from one list to another in Dart/Flutter
Try this:
main() {
var firstList = ["Travel", "Shopping", "Transport"];
var secondList = [
"Travel",
"Shopping",
"Shopping",
"Travel",
"Transport",
"Transport",
"Travel",
"Travel"
];
var thirdList = [];
for (var i = 0; i < secondList.length; i++) {
if (secondList[i] == "Travel") {
thirdList.add(i);
}
}
print(thirdList);
}
EDIT: For it to work for every item in firstList
Try this:
main() {
var firstList = ["Travel", "Shopping", "Transport"];
var secondList = [
"Travel",
"Shopping",
"Shopping",
"Travel",
"Transport",
"Transport",
"Travel",
"Travel"
];
var thirdList = [];
for (var i = 0; i < firstList.length; i++) {
var sublist = [];
for (var j = 0; j < secondList.length; j++) {
if (secondList[j] == firstList[i]) {
sublist.add(j);
}
}
thirdList.add(sublist);
}
print(thirdList); // [[0, 3, 6, 7], [1, 2], [4, 5]]
}
How do I find an index of an element in an array matching a condition and starting the search from a particular point in the array?
Using select
would return all values where the block returns true
for example:
p arr = ["abc", "d", "efg", "h", "abcde", "k"]
# => ["abc", "d", "efg", "h", "abcde", "k"]
p arr.each_index.select{|i| i >= 2 and arr[i].length == 1}
# => [3, 5]
Instead use detect
if you want to return only the first value where the block returns true
:
p arr = ["abc", "d", "efg", "h", "abcde", "k"]
# => ["abc", "d", "efg", "h", "abcde", "k"]
p arr.each_index.detect{|i| i >= 2 and arr[i].length == 1}
# => 3
Related Topics
Check If a String Contains Only Digits in Ruby
Issue Updating Ruby on MAC With Xcode 4.3.1
How to 'Validate' on Destroy in Rails
How to Force Rails_Env in a Rake Task
Regular Expressions With Validations in Ror 4
Weird Backslash Substitution in Ruby
How to Remove Emoji from String
Cannot Load Such File - Script/Rails: Getting This Error While Remote Debugging Through Rubymine
How to Convert a Ruby Hash Object to Json
Add a Default Value to a Column Through a Migration
How to Have Ruby Logger Log Output to Stdout as Well as File
How to Check If a Url Is Valid
How to Set Default Values in Rails