Removing value from array if it is contained by another array - arrays

I have two arrays
main_array = [[0,[1,4,5]], [1,[4,6,8]], [2,[5,6,7,8]], [3,[9,8]], [4,[7,2]]]
other_array = [[1,4,5],[9,8]]
What I want to do is to delete those elements in main_array if it can be found in other_array. (Meaning I will be left with [[1,[4,6,8]], [2,[5,6,7,8]],[4,[7,2]]] ) So I did the following:
other_array.each { |x|
for i in 0..main_array.length-1
main_array.delete(x)
}
It didn't work. Any clues on how I should approach this?

main_array.reject { |_,a| other_array.include?(a) }
#=> [[1,[4,6,8]], [2,[5,6,7,8]], [4,[7,2]]]

You can use Enumerable#reject (this is a module that is included in almost all collections in Ruby, such as Arrays, Hashes, Sets and etc.), it returns new array with removed elements, based on some condition:
main_array.reject { |item| other_array.include? item[1] }
Here item is every item in main_array. You can also "unwrap" your item if you want to control its elements individually:
main_array.reject { |(key, val)| other_array.include? val }
I'd recommend you to go and check the link above, there are also lots of interesting things over there.

Related

Enumerable#each_slice in Ruby

I am trying to push through this code. I want to reorganize an array into slices of 2 and then sort each slice alphabetically.
This is the code I’ve written but it’s showing up as failure.
def sorted_pairs(array)
sorted_pairs = []
array.each_slice(2).to_a { |group| sorted_pairs << group.sort }
end
You have the right idea using each_slice. What each_slice gives you (assuming you don't give it a block) is an enumerator, and you want to do some work to each element of that enumerator. In your case, that "work" is sorting the sublist. When we want to do something for each element of a list and produce a new list as result, that's a map operation.
array.each_slice(2).map { |group| group.sort }
And { |group| group.sort } is just a named method call, so it can be shortened using Symbol#to_proc.
array.each_slice(2).map(&:sort)

Get the index of the last occurrence of each string in an array

I have an array that is storing a large number of various names in string format. There can be duplicates.
let myArray = ["Jim","Tristan","Robert","Lexi","Michael","Robert","Jim"]
In this case I do NOT know what values will be in the array after grabbing the data from a parse server. So the data imported will be different every time. Just a list of random names.
Assuming I don't know all the strings in the array I need to find the index of the last occurrence of each string in the array.
Example:
If this is my array....
let myArray = ["john","john","blake","robert","john","blake"]
I want the last index of each occurrence so...
blake = 5
john = 4
robert = 3
What is the best way to do this in Swift?
Normally I would just make a variable for each item possibility in the array and then increment through the array and count the items but in this case there are thousands of items in the array and they are of unknown values.
Create an array with elements and their indices:
zip(myArray, myArray.indices)
then reduce into a dictionary where keys are array elements and values are indices:
let result = zip(myArray, myArray.indices).reduce(into: [:]) { dict, tuple in
dict[tuple.0] = tuple.1
}
(myArray.enumerated() returns offsets, not indices, but it would have worked here too instead of zip since Array has an Int zero-based indices)
EDIT: Dictionary(_:uniquingKeysWith:) approach (#Jessy's answer) is a cleaner way to do it
New Dev's answer is the way to go. Except, the standard library already has a solution that does that, so use that instead.
Dictionary(
["john", "john", "blake", "robert", "john", "blake"]
.enumerated()
.map { ($0.element, $0.offset) }
) { $1 }
Or if you've already got a collection elsewhere…
Dictionary(zip(collection, collection.indices)) { $1 }
Just for fun, the one-liner, and likely the shortest, solution (brevity over clarity, or was it the other way around? :P)
myArray.enumerated().reduce(into: [:]) { $0[$1.0] = $1.1 }

How to remove item from ArrayList in Kotlin

var arrayone: ArrayList<String> = arrayListOf("a","b","c")
val arraytwo:ArrayList<String> = arrayListOf(arrayone.removeAt(0))
for (item in arraytwo) {
println(item)
}
I just want to remove item from the first array and make a new array. But this just prints one item at index 0
removeAt(0) removes the first element from the first list and returns it. arrayListOf then uses that removed item to create a new (the second) list.
arrayone then contains: b and c. arraytwo then contains a.
You may want to use drop instead, if you didn't want to touch the first list and if you only wanted to add the remaining items to the new list, e.g.:
var arrayone: ArrayList<String> = arrayListOf("a","b","c")
val arraytwo = arrayone.drop(1)
for (item in arraytwo) {
println(item) // now prints all except the first one...
}
// arrayone contains: a, b, c
// arraytwo contains: b, c
Or use dropLast(1) if you want to drop only the last item. Or use dropWhile/dropLastWhile if you have a condition to apply and drop all until/upto that condition...
If you really want to remove items from the first and add only the removed ones to the second list, then your current approach is ok. If you however wanted to remove items at specific index and have a new list instead just containing the not-removed ones, you need to construct a copy of the first list first and then apply your removeAt on that list, e.g.:
val arraytwo = arrayone.toMutableList().apply {
removeAt(0)
}
// or without the apply:
arraytwo.removeAt(0)
Or you may use filterIndexed to solve that:
val arraytwo = arrayone.filterIndexed { index, _ ->
index != 1 // you can also specify more interesting filters here...
} // filter, map, etc. all return you a new list. If that list must be mutable again, just add a .toMutableList() at the end
By using filterIndexed, filter, drop, etc. you ensure that the first list is kept untouched. If you didn't want to touch the first list in the first place, you may rather want to use listOf or toList, i.e. just a List as type instead, which does not expose mutable functions (check also Kotlin reference regarding Collections: List, Set, Map).
Maybe you are also interested in filter/filterNot and then soon in minus or similar functions to remove unwanted items without index.
removeAt returns the removed element:
abstract fun removeAt(index: Int): E (source)
Removes an element at the specified index from the list.
Return the element that has been removed.
kotlin.stdlib / kotlin.collections.MutableList.removeAt
You're making a new list with one element, the element you removed.
Try:
val arraytwo = ArrayList(arrayone) // Copy the list
arraytwo.removeAt(0)
You never clarified if you want to modify the original list. If you do, just do arrayone.removeAt(0). That's it.
You can also make use of apply:
val arraytwo = ArrayList(arrayone).apply { removeAt(0) }
If you only need to remove items at the start or end, you can use drop (to remove items at the start) or dropLast, but as far as I know there is no collection extension to drop an item in the middle of an iterable (and judging by your comment, you seem to need this.) This makes sense, since an iterable has no concept of size or index.
If you just want to filter one certain element of your array you can use .filterTo(destination, predicate).
For your example it can look like this:
val arrayone = arrayListOf<String>("a", "b", "c")
val arraytwo = arrayListOf<String>()
arrayone.filterTo(arraytwo, { it != "a" })
println(arrayone) //[a, b, c]
println(arraytwo) //[b, c]
For Normal ArrayList:
val arrList = arrayListOf("account", "bec", "csw", "account")
arrList.removeAll { it == "account" }
For Custom ArrayList:
arrList.removeAll { it.key == "account" }
try this ,
var arrayone: ArrayList<String> = arrayListOf("a","b","c")
arrayone.removeAt(0)
val arraytwo:ArrayList<String> = arrayListOf(arrayone)
for (item in arraytwo) {
println(item)
}
val x = arrayListOf(1, 2, 3, 5)
x.removeFirst()
println(x)
val y = x.filterIndexed { index, value -> index != 0 }
println(y)
Output:
[2, 3, 5]
[3, 5]
GL
Source

Ruby - elegantly flatten an array but don't ignore empty sub-arrays

Using .flatten is a handy little trick to take an array of sub-arrays and turn it into a single array.
For example: [[1,3],2,[5,8]].flatten => [1,3,2,5,8]
You can even include nil [1,[2,nil],3].flatten will result in [1,2,nil,3].
This kind of method is very useful when nesting a .map method, but how would you account for an empty sub-array? For example: [1,[2,3],[],4].flatten would return [1,2,3,4]... but what if I need to keep track of the empty sub array maybe turn the result into [1,2,3,0,4] or [1,2,3,nil,4]
Is there any elegant way to do this? Or would I need to write some method to iterate through each individual sub-array and check it one by one?
If you don't need to recursively check nested sub-arrays:
[1,[2,3],[],4].map { |a| a == [] ? nil : a }.flatten
First map the empty arrays into nils, then flatten
[1,2,[1,2,3],[]].map{|x| if x.is_a? Array and x.empty? then nil else x end}.flatten

Take two arrays of strings and return an array with the combinations of the items in them

I need to take two arrays and return a single array with the combination of the items in them, listing the first items first. Like so:
combinations(["on","in"],["to","rope"])
# => ["onto","onrope","into","inrope"]
I've written a method that does this, but after that, I can't figure out where to go.
Use Array#product:
["on","in"].product(["to","rope"]).map(&:join)
# => ["onto", "onrope", "into", "inrope"]
def combinations(ary1, ary2)
ary1.map {|i| ary2.map {|i2| "#{i}#{i2}" }}.flatten
end

Resources