score:13
This is the use case of filter
:
scala> List(1,2,3,4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> res0.filter(_ != 2)
res1: List[Int] = List(1, 3, 4, 5)
You want to use map when you are transforming all the elements of a list.
score:0
The answer I am about to give might be overstepping what you have been taught so far in your course, so if that is the case I apologise.
Firstly, you are right to question whether you should have four lists - fundamentally, it sounds like what you need is an object which represents a course:
/**
* Represents a course.
* @param name the human-readable descriptor for the course
* @param time the time of day as an integer equivalent to
* 12 hour time, i.e. 1130
* @param meridiem the half of the day that the time corresponds
* to: either "am" or "pm"
* @param days an encoding of the days of the week the classes runs.
*/
case class Course(name : String, timeOfDay : Int, meridiem : String, days : Int)
with which you may define an individual course
val cs101 =
Course("CS101 - Introduction to Object-Functional Programming",
1000, "am", 1)
There are better ways to define this type (better representations of 12-hour time, a clearer way to represent the days of the week, etc), but I won't deviate from your original problem statement.
Given this, you would have a single list of courses:
val courses = List(cs101, cs402, bio101, phil101)
And if you wanted to find and remove all courses that matched a given name, you would write:
val courseToRemove = "PHIL101 - Philosophy of Beard Ownership"
courses.filterNot(course => course.name == courseToRemove)
Equivalently, using the underscore syntactic sugar in Scala for function literals:
courses.filterNot(_.name == courseToRemove)
If there was the risk that more than one course might have the same name (or that you are filtering based on some partial criteria using a regular expression or prefix match) and that you only want to remove the first occurrence, then you could define your own function to do that:
def removeFirst(courses : List[Course], courseToRemove : String) : List[Course] =
courses match {
case Nil => Nil
case head :: tail if head == courseToRemove => tail
case head :: tail => head :: removeFirst(tail)
}
score:0
Use the ListBuffer is a mutable List like a java list
var l = scala.collection.mutable.ListBuffer("a","b" ,"c")
print(l) //ListBuffer(a, b, c)
l.remove(0)
print(l) //ListBuffer(b, c)
score:2
Removing and filtering List elements
In Scala you can filter the list to remove elements.
scala> val courses = List("Artificial Intelligence", "Programming Languages", "Compilers", "Networks", "Databases")
courses: List[java.lang.String] = List(Artificial Intelligence, Programming Languages, Compilers, Networks, Databases)
Let's remove a couple of classes:
courses.filterNot(p => p == "Compilers" || p == "Databases")
You can also use remove but it's deprecated in favor of filter or filterNot.
If you want to remove by an index you can associate each element in the list with an ordered index using zipWithIndex
. So, courses.zipWithIndex
becomes:
List[(java.lang.String, Int)] = List((Artificial Intelligence,0), (Programming Languages,1), (Compilers,2), (Networks,3), (Databases,4))
To remove the second element from this you can refer to index in the Tuple with courses.filterNot(_._2 == 1)
which gives the list:
res8: List[(java.lang.String, Int)] = List((Artificial Intelligence,0), (Compilers,2), (Networks,3), (Databases,4))
Lastly, another tool is to use indexWhere
to find the index of an arbitrary element.
courses.indexWhere(_ contains "Languages")
res9: Int = 1
Re your update
I'm writing a function to remove the corresponding element from each lists, and all I know is that 1) the indices correspond and 2) the user inputs the course name. How can I remove the corresponding element from each list using filterNot?
Similar to Nikita's update you have to "merge" the elements of each list. So courses, meridiems, days, and times need to be put into a Tuple or class to hold the related elements. Then you can filter on an element of the Tuple or a field of the class.
Combining corresponding elements into a Tuple looks as follows with this sample data:
val courses = List(Artificial Intelligence, Programming Languages, Compilers, Networks, Databases)
val meridiems = List(am, pm, am, pm, am)
val times = List(100, 1200, 0100, 0900, 0800)
val days = List(MWF, TTH, MW, MWF, MTWTHF)
Combine them with zip:
courses zip days zip times zip meridiems
val zipped = List[(((java.lang.String, java.lang.String), java.lang.String), java.lang.String)] = List((((Artificial Intelligence,MWF),100),am), (((Programming Languages,TTH),1200),pm), (((Compilers,MW),0100),am), (((Networks,MWF),0900),pm), (((Databases,MTWTHF),0800),am))
This abomination flattens the nested Tuples to a Tuple. There are better ways.
zipped.map(x => (x._1._1._1, x._1._1._2, x._1._2, x._2)).toList
A nice list of tuples to work with.
List[(java.lang.String, java.lang.String, java.lang.String, java.lang.String)] = List((Artificial Intelligence,MWF,100,am), (Programming Languages,TTH,1200,pm), (Compilers,MW,0100,am), (Networks,MWF,0900,pm), (Databases,MTWTHF,0800,am))
Finally we can filter based on course name using filterNot
. e.g. filterNot(_._1 == "Networks")
List[(java.lang.String, java.lang.String, java.lang.String, java.lang.String)] = List((Artificial Intelligence,MWF,100,am), (Programming Languages,TTH,1200,pm), (Compilers,MW,0100,am), (Databases,MTWTHF,0800,am))
score:3
First a few sidenotes:
List
is not an index-based structure. All index-oriented operations on it take linear time. For index-oriented algorithmsVector
is a much better candidate. In fact if your algorithm requires indexes it's a sure sign that you're really not exposing Scala's functional capabilities.map
serves for transforming a collection of items "A" to the same collection of items "B" using a passed in transformer function from a single "A" to single "B". It cannot change the number of resulting elements. Probably you've confusedmap
withfold
orreduce
.
To answer on your updated question
Okay, here's a functional solution, which works effectively on lists:
val (resultCourses, resultTimeList, resultAmOrPmList, resultDateList)
= (courses, timeList, amOrPmList, dateList)
.zipped
.filterNot(_._1 == input)
.unzip4
But there's a catch. I actually came to be quite astonished to find out that functions used in this solution, which are so basic for functional languages, were not present in the standard Scala library. Scala has them for 2 and 3-ary tuples, but not the others.
To solve that you'll need to have the following implicit extensions imported.
implicit class Tuple4Zipped
[ A, B, C, D ]
( val t : (Iterable[A], Iterable[B], Iterable[C], Iterable[D]) )
extends AnyVal
{
def zipped
= t._1.toStream
.zip(t._2).zip(t._3).zip(t._4)
.map{ case (((a, b), c), d) => (a, b, c, d) }
}
implicit class IterableUnzip4
[ A, B, C, D ]
( val ts : Iterable[(A, B, C, D)] )
extends AnyVal
{
def unzip4
= ts.foldRight((List[A](), List[B](), List[C](), List[D]()))(
(a, z) => (a._1 +: z._1, a._2 +: z._2, a._3 +: z._3, a._4 +: z._4)
)
}
This implementation requires Scala 2.10 as it utilizes the new effective Value Classes feature for pimping the existing types.
I have actually included these in a small extensions library called SExt, after depending your project on which you'll be able to have them by simply adding an import sext._
statement.
Of course, if you want you can just compose these functions directly into the solution:
val (resultCourses, resultTimeList, resultAmOrPmList, resultDateList)
= courses.toStream
.zip(timeList).zip(amOrPmList).zip(dateList)
.map{ case (((a, b), c), d) => (a, b, c, d) }
.filterNot(_._1 == input)
.foldRight((List[A](), List[B](), List[C](), List[D]()))(
(a, z) => (a._1 +: z._1, a._2 +: z._2, a._3 +: z._3, a._4 +: z._4)
)
score:13
To answer your question directly, I think you're looking for patch
, for instance to remove element with index 2 ("c"):
List("a","b","c","d").patch(2, Nil, 1) // List(a, b, d)
where Nil
is what we're replacing it with, and 1
is the number of characters to replace.
But, if you do this:
I have four lists that are associated with each other by index; one list stores the course names, one stores the time the class begins in a simple int format (ie 130), one stores either "am" or "pm", and one stores the days of the classes by int
you're going to have a bad time. I suggest you use a case class
:
case class Course(name: String, time: Int, ampm: String, day: Int)
and then store them in a Set[Course]
. (Storing time and days as Int
s isn't a great idea either - have a look at java.util.Calendar
instead.)
Source: stackoverflow.com
Related Query
- How can I idiomatically "remove" a single element from a list in Scala and close the gap?
- How can I remove duplicates from a list in Scala with pattern matching?
- how can I write a function in scala called Order that takes one arguement: a list of Ints. And returns the same List of Ints from least to greatest
- How to remove specific element from list, and group list elements using scala?
- How to find and remove an element from Scala ListBuffer?
- How to remove an item from a list in Scala having only its index?
- How to find a matching element in a list and map it in as an Scala API method?
- How to remove 2 or more duplicates from list and maintain their initial order?
- Scala Spark : How to create a RDD from a list of string and convert to DataFrame
- How can I select a non-sequential subset elements from an array using Scala and Spark?
- Remove one element from Scala List
- How can I pass a Scala UserDefinedFunction where output is a complex type (using StructType and StructField) to be used from Pyspark
- How can I shield implementation level classes, traits and objects from Scala public APIs?
- How to remove quotes from front and end of the string Scala
- Scala Play Json - how to read a single element from a element in an Array?
- How can I use memcached (Amazon elasticache) from both scala and rails simultaneously?
- how to remove every nth element from the Scala list?
- Remove element from List of Maps in Scala
- How can a Map or List be immutable when we can add or remove elements from them?
- How can I write a typeclass in scala on a container type, returning an element from the container?
- Calculate average and remove from list in Scala
- How would you pop an element from the end of a list in scala, and add it to the end of another list?
- scala list counting element and find indices from other list
- How do I remove an element from a list by value?
- How to find an element in a list based on a condition and return some data associated with that element in Scala
- How to filter second element in a tuple from a List in scala
- How to remove a string element from a list if its a subset of another element?
- how can I group rows from a DataFrame into a single row separated by a delimiter Scala Spark?
- Deleting an element from a List in Scala using a loop and only a loop
- Scala remove a single object from a list
More Query from same tag
- Scala: parse JSON file into List[DBObject]
- Convert base64 image to file in javascript or how to pass a big base64 string with jquery ajax
- com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.9.5
- Compose Scalaz validations
- Spark & Drools - How to serialize KieBase with Kryo
- Scala can't import a class that Java can
- Cannot mock the RedisClient class - method pipeline overrides nothing
- Error for partition in KAFKA
- How to view images from local directories in play scala project
- Scala console: OutOfMemoryError: GC overhead limit exceeded
- Create a range of dates in a pyspark DataFrame
- Play Framework version 2.6/2.7 set PLAY_SESSION cookie to SameSite=None; Secure
- FS2 stream run till the end of InputStream
- Apache Spark K-Means clustering - RDD for input
- Config library which allows to define scopes
- Spark : Writing data frame to s3 bucket
- Pass json file into JAR or read from spark session
- Why declare a function this verbosely?
- How to store the text file on the Master?
- How to pass a function with implicit as parameter
- How do i perform conditional check using Gatling
- How do I make a (minimal) runnable jar file from a scala eclipse project
- How to rename files in hdfs from spark more efficiently?
- Find difference of column value in spark using scala
- Why creating an actor within actor is dangerous
- Scala SBT CoffeeScripted, correctly override compile target
- How to run Main method in Scala in Intellij
- Why are Map and Set aliased in scala.Predef?
- Scala Play: Routes optional parameter with regex?
- I need to compare hive table schema with a data frame which contains schema of a csv file