I want to remove some elements from an array contained in another array.
The way to do this in Java is:
myArray.removeAll(anotherArray)
This code removes the elements contained in anotherArray from myArray.
Is there something like removing the elements contained in myArray INTERSECTION anotherArray from myArray?
Yes, this is what the - operator (really Array#- method) is for:
a = [1, 2]
b = [2]
a - b
# => [1]
Use "Array Difference"
There's more than one way to do this in Ruby, but the most common is to call the array difference method Array#-. The documentation for this method says:
Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. The order is preserved from the original array.
It compares elements using their hash and eql? methods for efficiency.
[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
If you need set-like behavior, see the library class Set.
The minus sign looks like an operator, but is actually a method call on the first Array object. Obviously, you could also look at Set#difference if you're working with Set objects rather than an Array.
Related
Honestly I have no idea how to check if list 1 contains every element from 2nd list, but I need it.
EDIT: i want to check if those 2 lists with same length have the same values, just with different indices
Thank you in advance
Something like this?
void main() {
final list1 = [5, 2, 3, 10, 2, 1, 11, 4];
final list2 = [1, 2, 3, 4, 5];
print(list1.toSet().containsAll(list2)); // true
}
First of all, you need to specify what you mean by "same elements". Do you mean equal elements (according to ==) or identical elements (according to the identical function)? I'm going to assume ==, since that's the most common, and if your elements don't override ==, it's the same thing as identity anyway.
The simplest approach, if possible, is to sort both lists, then compare each element of one list to the element of the other list at the same position. That does require that the elements have an ordering that agrees with == (so a.compareTo(b) == 0 if and only if a == b), and that you are allowed to change the ordering of the lists.
If you do almost anything else, you need to consider what happens if the same element occurs more than once in one of the lists.
Just comparing lengths as well is not enough, since [1, 1, 2] and [1, 2, 2] both have three elements, and all elements of either list is also an element of the other list. If duplicate elements can occur, you need to be counting the elements as well.
You can use UnorderedIterableEquality from package:collection. It implements a counting-based equality check on arbitrary iterables, which includes working on lists.
Example:
const unorderedEquals = UnorderedIterableEquality();
// ...
if (unorderedEquals.equals(list1, list2)) {
// ... lists have same elements ...
}
How can I change subscript coordinates in an Array of Arrays [[Int]] so that the way to address a cell would be table[column-letter][row-number], same as Excel, instead of current ios table[row-number][column-number] for a given table like:
var table = [[0, 1, 2, 3],
[1, 32, 44, 25],
[2, 12, 66, 43],
[3, 3, 4, 5]]
Today table[2][1] = 12, but I want table[C][1] = 44.
I need this change to adapt formulas from excel into my app without changing the coordinate system or the tables from an Excel.
I know there are subscript functions in Array class which may help, but I couldnĀ“t make it work so far.
Today table2 = 12, but I want tableC = 44.
Do you know what is [2][1] actually means you are telling the compiler,
i want the element in the array that has index of [2] and by adding another [1], you are telling it that you need the element that has index of [1] that its inside the result of [2].
its an Array of Arrays if you take another look at it empty would be something like this ,
[[],[],[]] // no matter what is the values inside indexing is always the same
with that pointed out now lets take a look on what are you trying to do.
[C][1] = 44
As you can now probably tell this is not valid because [C] is not a valid index as index accept only Integer Types.
So what can we try ?.
Well you can try dictionaries
Read about them here
With dictionary at some point you will be able to get a value like this
value = table["C"]?[1]
or take a look on this example.
var foo :[String:[Int]] = ["A":[1,2,3], "B":[1,2,3]]
let colm = foo["A"]?[0]
Edit another solution inspired by #Paulw11
using this "A".utf16.first! - 65 will return 0 index to use inside the Array so you can additionally say from A to Z
table = ["MyChar".utf16.first! - 65][2]
I was just reading some introductory stuff from GameMonkey Script on https://www.gamedev.net/articles/programming/engines-and-middleware/introduction-to-gamemonkey-script-r3297/ and when they were explaining about Mixed Arrays they say that you can access the elements using and index or a key depending on how the value was declared, so for example if i have the next array
myMixedArray = table( 1, 3, 4, KeyV = "Test", 33);
then i can access 1, 2, 4 and 33 using the next indices 0, 1, 2, 3 and
to access "Test" i'll do it like this
myMixedArray["KeyV"] <- ("Test")
now according with the following image that you can find in the above link
The number expected to be at myTest[3] is 7, but that would mean that both regular values and key-val elements are not really separated in the array.
If not then why would 7 be at the index 3 of the array?
While you can treat a gm Table as an Array or Map, you can't effectively do both at the same time.
Internally, the Table is just a hash table, and your index access method is a bit like an iterator.
In your example, because value "Test" is assigned to key 'KeyV', it messes up the otherwise contiguous index order.
Hopefully that gives you an idea of the cause. Try iterating a table with no 'keys' and again with all key value pairs. Observe the different behavior.
If you are serious about arrays, you may be better off using a binding to create an Array type with the behavior you want. GM source has an example of an array container.
I am working on a feature on an open source project.
At some point a CSV file is imported and I create an array out of it to pass it in a new object.
After
CSV.open(path, 'rb', opts)
this is used to get the block of code
.tap { |c| yield c if block_given? }
My question is, how to get access to the data imported?
After tap there is a method sequence.
Edit:
I don't want to re-write it I want to test it. I know I am supposed to use tap to modify the data, but I don't know how to do that as I don't see any way to reference the data of the CSV
It does not really have anything to do with file manipulation at this point. It's more about understanding how #tap and blocks work.
def block
[1, 2, 3, 4, 5].tap { |array| yield array if block_given?}
end
block { |array| array.each{ |element| puts element } }
The output:
1
2
3
4
5
In a method block, an array [1, 2, 3, 4, 5] is initialized, afterwards we tap into that array, which makes that array available in the tap's block.
In the example above, when [1, 2, 3, 4, 5] is passed to tap it is available in array variable, which is specified like this: |array|. Then array is yield to the block if block_given?. That means that in the new block |array| contains [1, 2, 3, 4, 5] too. So in that new block that you pass to tap, you can modify that array, or just output it like I did.
I have a method that iterates over an array, does a bunch of stuff under certain conditions and depending on these conditions I would ALSO like to delete some of the elements. In order to keep track of the indexes I like to delete I converted the each in to an each_with_index loop and store the index of the elements that I like to delete in an array index_array. How can I delete exactly the items on those indexes in my original array? Looping over the index_array and using delete_at would change the original index. Please see below description of the scenario:
> my_array = [0,1,2,3,4,5,6,7]
> delete_these_indexes = [1,2,5]
the desired result is:
> my_array => [0,3,4,6,7,8]
How about this?
my_array = [0, 1, 2, 3, 4, 5, 6, 7]
delete_these_indices = [1, 2, 5]
delete_these_indices.sort.reverse_each {|i| my_array.delete_at(i) }
p my_array
# => [0, 3, 4, 6, 7, 8]
It's important to delete from the end of the array, since deleting an item will change the indices of all subsequent items, ergo sort.reverse_each. If you know the array is already sorted, you can just do reverse_each.
If you don't care bout modifying the delete_these_indices array, you can be somewhat more terse:
delete_these_indices.sort!
my_array.delete_at(i) while (i = delete_these_indices.pop)
Again, you can skip sort! if you know delete_these_indices is already sorted.
keep_these_indexes = my_array.each_index.to_a - delete_these_indexes
#=> [0, 3, 4, 6, 7]
If you wish to modify my_array (which appears to be the case):
my_array.replace(my_array.values_at(*keep_these_indexes))
#=> [0, 3, 4, 6, 7]
If not:
new_array = my_array.values_at(*keep_these_indexes)
See Array#values_at.
delete_these_indexes.each_with_index do |val, i|
my_array.delete_at(val - i)
end
deletes at the desired index taking into account how many have previously been deleted and adjusting for that
https://repl.it/CeHZ
Probably not the best answer, but you can do this as well:
delete_at_indices.each {|ind| my_array[ind] = nil }
my_array.delete(nil)
Takes a first pass to conceptually invalidate the data at the specified indices, then the call to .delete will blow out any values that match what's passed in.
This solution assumes that you can define a value that isn't valid for your array. Using nil will be problematic if you're treating this as a sparsely populated array (where nil is a valid value)
Technically you're iterating through each array once, but that Gentleman's Agreement on what your deletable value might make some people uncomfortable