removing array elements by indexes from an array ruby - ruby

I have an array of words like so
["jo","jibber","hail","noobs","smirk","awkland"]
and a seperate array with indexes
[0,3,5]
I want to remove all the elements from the previous array at those indexes.
I was thinking i could use reject but im not sure exactly how i would do it. Also once i remove one element wont all the other indexes would have to change.
Is there an easy way of doing this??

You can use reject and with_index
arr = ["jo", "jibber", "hail", "noobs", "smirk", "awkland"]
indexes = [0, 3, 5]
arr.reject.with_index {|_, idx| indexes.include?(idx)} # => ["jibber", "hail", "smirk"]

Related

Can I use index to get a set element in Ruby?

Suppose I have a set in Ruby s1:
#<Set: {12, 25}>
I use s1.find_index(12) to get the index 0
Can I use the index to get back the set element, something like s1[0] to get back 12?
The reason I want to do this is my set elements are large. I want to store links between the set elements. I use the index to store the links.
I am using Ruby 1.9.3
I think you want to use an Array and a Hash for this.
ary = []
hsh = {}
unless hsh[item]
hash[item] = ary.size
ary << item
end
Then when you look up the item in hsh later you will have the index of the item in the list and effectively you will have the internals of your set with a specific caveat
That might not be possible. Set is an unordered list.
Set implements a collection of unordered values with no duplicates. This is a hybrid of Array's intuitive inter-operation facilities and Hash's fast lookup.
You can get an element from a set by its index in this way:
my_set = Set.new([1, 4, 7])
if index = my_set.find_index(4)
puts my_set.to_a[index]
end

Ruby array subtraction?

Either I don't understand what happens when you subtract an array from an array, or something is wrong here.
What I have is a list of usernames (strings) in an array:
users.count - users.uniq.count # => 9
users - users.uniq # => []
I'm not sure how this is possible.
I'm essentially trying to find a list of the duplicates. I realize there are other ways to go about this, just trying to understand Array operations better.
Here is the workaround code I used to get the same:
users.inject(Hash.new(0)) {|h,i| h[i] += 1; h}.select{|k,v| v > 1}
You could use
dups = users.select{|e| users.count(e) > 1 }.uniq
Or, to find only a single duplicate element:
firstDup = users.detect {|e| users.count(e) > 1 }
About the array subtraction, this may clarify:
a = [1, 1, 1, 1, 1]
a - [1] # => []
Array subraction removes all occurences, not just one.
The behavior of Array#- is quite correct. It
Returns a new array that is a copy of the original array, removing any
items that also appear in other_ary.
The user list (with duplicates) without all the users is empty.
Coming from "Ruby: How to find and return a duplicate value in array?", the following seems to be good at finding duplicates in an Array:
users.detect {|e| users.rindex(e) != users.index(e) }

Index a ruby array to omit an element or range of elements?

I have a ruby array of, say, 10 elements, and I'd like to return all but the 5th element.
a = *(1..10)
I'd like to be able to do something like
a[0..3 + 5..9]
Or even better something like (borrowing from the R syntax),
a[-4]
to do this, but that doesn't work. (Nor does anything more clever I've tried like getting an array of the element indices). What's the best way to do this in ruby?
You can use values_at: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-values_at
so you may use it as
a.values_at(0..3, 5..9)
No black magic required:
a[0..3] + a[5..9]
Look in the documentation under Array#delete_at
For example, myarray.delete_at(5) results in the array lacking what was element 5 (counting from 0, of course).
Example:
class Array
def without(n)
self.delete_at(n)
return self
end
end
arr = [1, 2, 3, 4]
p arr.without(1) #=> [1, 3, 4]
However, as a commenter points out, this alters the original array, which may not be what the O.P. wants! If that's an issue, write it like this:
class Array
def without(n)
arr2 = Array.new(self)
arr2.delete_at(n)
return arr2
end
end
That returns the desired array (an array lacking the nth element of the original) while leaving the original array untouched.

Ruby: Selecting a set of array indices whose elements pass a test

Ruby has a select method that takes an array and returns a subarray consisting of all the elements that pass the test given in a block:
myarray.select{|e| mytest(e)} #=> subarray of elements passing mytest
I am wondering whether there is a simple method to get not these elements, but their indices. I understand you could do this:
indices = []
myarray.each_with_index{|e,i| indices << i if mytest(e)}
But I'm looking for a one-liner. Does one exist? Please don't write an extension to the Array class, I know you can get a one-liner that way.
Another one-liner:
(0...myarray.length).select {|i| mytest(myarray[i])}
Cheers!
Here's a one-liner for you. It selects indexes of elements whose length is 3.
a = ['foo', 'bar', 't']
a.map.with_index{|el, i| i if el.length == 3}.compact # => [0, 1]
Or another one (suggested by #fl00r):
a.reduce([]){|ar,el| ar << a.index(el) if el.size == 3; ar}
Also,
myarray.select{|e| mytest(e)}.map!{|e| myarray.index(e)}
However, this won't work properly if you have any repeated elements.

Ruby: hash that doesn't remember key values

Is there a hash implementation around that doens't remember key values? I have to make a giant hash but I don't care what the keys are.
Edit:
Ruby's hash implementation stores the key's value. I would like hash that doesn't remember the key's value. It just uses the hash function to store your value and forgets the key. The reason for this is that I need to make a hash for about 5 gb of data and I don't care what the key values are after creating it. I only want to be able to look up the values based on other keys.
Edit Edit:
The language is kind of confusing. By key's value I mean this:
hsh['value'] = data
I don't care what 'value' is after the hash function stores data in the hash.
Edit^3:
Okay so here's what I am doing: I am generating every 35-letter (nucleotide) kmer for a set of multiple genes. Each gene has an ID. The hash looks like this:
kmers = { 'A...G' => [1, 5, 3], 'G...T' => [4, 9, 9, 3] }
So the hash key is the kmer, and the value is an array containing IDs for the gene(s)/string(s) that have that kmer.
I am querying the hash for kmers in another dataset to quickly find matching genes. I don't care what the hash keys are, I just need to get the array of numbers from a kmer.
>> kmers['A...G']
=> [1, 5, 3]
>> kmers.keys.first
=> "Sorry Dave, I can't do that"
I guess you want a set, allthough it stores unique keys and no values. It has the fast lookup time from a hash.
Set is included in the standard libtrary.
require 'set'
s = Set.new
s << 'aaa'
p s.merge(['ccc', 'ddd']) #=> #<Set: {"aaa", "ccc", "ddd"}>
Even if there was an oddball hash that just recorded existence (which is how I understand the question) you probably wouldn't want to use it, as the built-in Hash would be simpler, faster, not require a gem, etc. So just set...
h[k] = k
...and call it a day...
I assume the 5 gb string is a genome, and the kmers are 35 base pair nucleotide sequences.
What I'd probably do (slightly simplified) is:
human_genome = File.read("human_genome.txt")
human_kmers = Set.new
human_genome.each_cons(35) do |potential_kmer|
human_kmers << potential_kmer unless human_kmers.include?(potential_kmer)
end
unknown_gene = File.read("unknown_gene.txt")
related_to_humans = unknown_gene.each_cons(35).any? do |unknown_gene_kmer|
human_kmers.include?(unknown_gene_kmer)
end
I have to make a giant hash but I don't care what the keys are.
That is called an array. Just use an array. A hash without keys is not a hash at all and loses its value. If you don't need key-value lookup then you don't need a hash.
Use an Array. An Array indexes by integers instead of keys. http://www.ruby-doc.org/core/classes/Array.html
a = []
a << "hello"
puts a #=> ["hello"]

Resources