I have following list
List(List
(43673,38448,512,36398,1500,**BpEwv+EcDv3z**,58f39535-03b7-4e05-a2d8-3f5b424c8938),
List(302750,759,512,759,3796,**BpEwv+EcDv3v**,069865df-30c3-48c3-bf02-79f2fcff7213),
List(616278,1600,512,107418,15255,**BpEwv+EcDv3v**,b373b731-6f38-4559-808e-1c05fc06af00),
List(0,0,512,0,0,**BpEwv+EcDv3z**,24894b9f-9e30-4073-a538-186a312c670e)
)
I want to remove duplicate values marked in bold (6th index of list for all elements) from this list. The sequence of elements is fixed.
Expected output:
List(
List(43673,38448,512,36398,1500,BpEwv+EcDv3z,58f39535-03b7-4e05-a2d8-3f5b424c8938),
List(302750,759,512,759,3796,BpEwv+EcDv3v,069865df-30c3-48c3-bf02-79f2fcff7213))
How do I remove duplicate values from list using scala??
If you want to remove all occurrences of a specific value in all Lists you can use the following code:
val lss = List(List(1,2,2), List(1,2,3,4,2))
lss map (_.filter(_ != 2)) // List(List(1), List(1, 3, 4))
which removes all occurrences of 2 in all Lists.
If you want to get a single List in return you can use flatMap:
lss flatMap (_.filter(_ != 2)) // List(1, 1, 3, 4)
Based on your expected output, you can do something like
scala> val a = List(List
| (43673,38448,512,36398,1500,"BpEwv+EcDv3z","58f39535-03b7-4e05-a2d8-3f5b424c8938"),
| List(302750,759,512,759,3796,"BpEwv+EcDv3v","069865df-30c3-48c3-bf02-79f2fcff7213"),
| List(616278,1600,512,107418,15255,"BpEwv+EcDv3v","b373b731-6f38-4559-808e-1c05fc06af00"),
| List(0,0,512,0,0,"BpEwv+EcDv3z","24894b9f-9e30-4073-a538-186a312c670e")
| )
a: List[List[Any]] = List(List(43673, 38448, 512, 36398, 1500, BpEwv+EcDv3z, 58f39535-03b7-4e05-a2d8-3f5b424c8938), List(302750, 759, 512, 759, 3796, BpEwv+EcDv3v, 069865df-30c3-48c3-bf02-79f2fcff7213), List(616278, 1600, 512, 107418, 15255, BpEwv+EcDv3v, b373b731-6f38-4559-808e-1c05fc06af00), List(0, 0, 512, 0, 0, BpEwv+EcDv3z, 24894b9f-9e30-4073-a538-186a312c670e))
scala> a.groupBy(_(5)).mapValues(_(0)).map(_._2)
res0: scala.collection.immutable.Iterable[List[Any]] = List(List(302750, 759, 51
2, 759, 3796, BpEwv+EcDv3v, 069865df-30c3-48c3-bf02-79f2fcff7213), List(43673, 3
8448, 512, 36398, 1500, BpEwv+EcDv3z, 58f39535-03b7-4e05-a2d8-3f5b424c8938))
You can also do which reads a little better
scala> a.groupBy(_(5)).mapValues(_(0)).values.toList
res6: List[List[Any]] = List(List(302750, 759, 512, 759, 3796, BpEwv+EcDv3v, 069865df-30c3-48c3-bf02-79f2fcff7213), List(43673, 38448, 512, 36398, 1500, BpEwv+EcDv3z, 58f39535-03b7-4e05-a2d83f5b424c8938))
Related
I am trying to divide a list of string into 4 sublist (which should have all elements of original list balanced among them). I have tried following approach but i am getting reminder elements into a 5th list. I need only four sublists and reminder must be adjusted into these four list only
def sublists = localities.collate(localities.size().intdiv(4))
for(sublist in sublists){
println(sublist.join(','))
println "next"
}
here localities is having around 163 elements, I am getting output as 4 list of 40 and 5th list of size 3.. my localities list is dynamic and could have variable number (will always be above 100) . i need to get only 4 list, where reminder of 3 elements are adjusted in 4 list.
Something like this:
def split( list ){
int size = Math.ceil( list.size() / 4 )
list.collate size
}
assert split( 1..163 )*.size() == [41, 41, 41, 40]
assert split( 1..157 )*.size() == [40, 40, 40, 37]
assert split( 1..100 )*.size() == [25, 25, 25, 25]
assert split( 1..4 )*.size() == [1, 1, 1, 1]
//edge cases
assert split( 1..3 )*.size() == [1, 1, 1]
assert split( 1..2 )*.size() == [1, 1]
// for all lengths above 4 exactly 4 groups are returned
4..200.each{
assert split( 1..it ).size() == 4
}
In Raku, how does one write the equivalent of Haskell's span function?
In Haskell, given a predicate and a list, one can split the list into two parts:
the longest prefix of elements satisfying the predicate
the remainder of the list
For example, the Haskell expression …
span (< 10) [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4]
… evaluates to …
([2,2,2,5,5,7],[13,9,6,2,20,4])
How does one write the Raku equivalent of Haskell's span function?
Update 1
Based on the answer of #chenyf, I developed the following span subroutine (additional later update reflects negated predicate within span required to remain faithful to the positive logic of Haskell's span function) …
sub span( &predicate, #numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = #numberList.first(&negatedPredicate):k ;
my #lst is Array[List] = #numberList[0..$idx-1], #numberList[$idx..*] ;
#lst ;
} # end sub span
sub MAIN()
{
my &myPredicate = { $_ <= 10 } ;
my #myNumberList is Array[Int] = [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4] ;
my #result is Array[List] = span( &myPredicate, #myNumberList ) ;
say '#result is ...' ;
say #result ;
say '#result[0] is ...' ;
say #result[0] ;
say #result[0].WHAT ;
say '#result[1] is ...' ;
say #result[1] ;
say #result[1].WHAT ;
} # end sub MAIN
Program output is …
#result is ...
[(2 2 2 5 5 7) (13 9 6 2 20 4)]
#result[0] is ...
(2 2 2 5 5 7)
(List)
#result[1] is ...
(13 9 6 2 20 4)
(List)
Update 2
Utilizing information posted to StackOverflow concerning Raku's Nil, the following updated draft of subroutine span is …
sub span( &predicate, #numberList )
{
my &negatedPredicate = { ! &predicate($^x) } ;
my $idx = #numberList.first( &negatedPredicate ):k ;
if Nil ~~ any($idx) { $idx = #numberList.elems ; }
my List $returnList = (#numberList[0..$idx-1], #numberList[$idx..*]) ;
$returnList ;
} # end sub span
sub MAIN()
{
say span( { $_ == 0 }, [2, 2, 5, 7, 4, 0] ) ; # (() (2 2 5 7 4 0))
say span( { $_ < 6 }, (2, 2, 5, 7, 4, 0) ) ; # ((2 2 5) (7 4 0))
say span( { $_ != 9 }, [2, 2, 5, 7, 4, 0] ) ; # ((2 2 5 7 4 0) ())
} # end sub MAIN
I use first method and :k adverb, like this:
my #num = [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4];
my $idx = #num.first(* > 10):k;
#num[0..$idx-1], #num[$idx..*];
A completely naive take on this:
sub split_on(#arr, &pred) {
my #arr1;
my #arr2 = #arr;
loop {
if not &pred(#arr2.first) {
last;
}
push #arr1: #arr2.shift
}
(#arr1, #arr2);
}
Create a new #arr1 and copy the array into #arr2. Loop, and if the predicate is not met for the first element in the array, it's the last time through. Otherwise, shift the first element off from #arr2 and push it onto #arr1.
When testing this:
my #a = [2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4];
my #b = split_on #a, -> $x { $x < 10 };
say #b;
The output is:
[[2 2 2 5 5 7] [13 9 6 2 20 4]]
Only problem here is... what if the predicate isn't met? Well, let's check if the list is empty or the predicate isn't met to terminate the loop.
sub split_on(#arr, &pred) {
my #arr1;
my #arr2 = #arr;
loop {
if !#arr2 || not &pred(#arr2.first) {
last;
}
push #arr1: #arr2.shift;
}
(#arr1, #arr2);
}
So I figured I'd throw my version in because I thought that classify could be helpful :
sub span( &predicate, #list ) {
#list
.classify({
state $f = True;
$f &&= &predicate($_);
$f.Int;
}){1,0}
.map( {$_ // []} )
}
The map at the end is to handle the situation where either the predicate is never or always true.
In his presentation 105 C++ Algorithms in 1 line* of Raku (*each) Daniel Sockwell discusses a function that almost answers your question. I've refactored it a bit to fit your question, but the changes are minor.
#| Return the index at which the list splits given a predicate.
sub partition-point(&p, #xs) {
my \zt = #xs.&{ $_ Z .skip };
my \mm = zt.map({ &p(.[0]) and !&p(.[1]) });
my \nn = mm <<&&>> #xs.keys;
return nn.first(?*)
}
#| Given a predicate p and a list xs, returns a tuple where first element is
#| longest prefix (possibly empty) of xs of elements that satisfy p and second
#| element is the remainder of the list.
sub span(&p, #xs) {
my \idx = partition-point &p, #xs;
idx.defined ?? (#xs[0..idx], #xs[idx^..*]) !! ([], #xs)
}
my #a = 2, 2, 2, 5, 5, 7, 13, 9, 6, 2, 20, 4;
say span { $_ < 10 }, #a; #=> ((2 2 2 5 5 7) (13 9 6 2 20 4))
say span { $_ < 5 }, [6, 7, 8, 1, 2, 3]; #=> ([] [6 7 8 1 2 3])
Version 6.e of raku will sport the new 'snip' function:
use v6.e;
dd (^10).snip( * < 5 );
#«((0, 1, 2, 3, 4), (5, 6, 7, 8, 9)).Seq»
Scala accessing list objects and evaluating number of cycles
I have list of objects
case class ItemDesc(a: Int, b: Int, c: Int, d: Int,e: Int, f: Int, g: Int desc: String)
val example = List(ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, The values are correct), ItemDesc(14879,-14879,14879,-14894, 14879,14879,14894, The values are ok), ItemDesc(19682,-19690,-19682,19694,19690,19682,19694,The values are good),ItemDesc(5164,-5165,-5166,-6195,5165,5166,6195,The values are correct),ItemDesc(5879,5879,5879,5894,5879,5879,5879,The values are ok))
From the 'example' List, I want to access object 'ItemDesc'. And get the count of cycles. how many times it turns from negative to positive and stays positive for >= 2 seconds.
If >= 2 seconds it is a cycle.
Example 1: (6164,6165,6166,-6195,-6175,-6186,-6195, good)
No. of cycles is 2.
Reason: As we move from 1st element of list to 3rd element, we had 2 intervals which means 2 seconds. Interval is >= 2. So it is one cycle. As we move to 3rd element of list to 4th element, it is a negative value. So we start counting from 4th element and move to 7th element and all elements have same negative sign. we had 3 intervals which means 3 seconds. Interval is >= 2. So it is one cycle. We start counting intervals fresh from zero as one number changes from positive to negative and vice-versa.
Example 2: (14879,-14879,14879,-14894, 14879,14879,14894,better)
No. of cycles is 1.
Reason: As we move from 1st element of list to 2nd element, the sign changes to negative. So we start counting the interval from zero. From element 2 to 3, the sign changes to negative. so interval counter is zero. From element 3 to 4, the sign changes to negative. interval counter is zero. From 5th to 7th all values have same sign, we had 2 intervals which means 2 seconds. Interval is >= 2. So it is one cycle.
Example 3: (5164,-5165,-5166,-6195,5165,5166,6195,good)
No. of cycles is 2
The below code which I wrote is not giving me the no. of cycles which I am looking for. Appreciate help in fixing it.
object findCycles {
def main(args: Array[String]) {
var numberOfPositiveCycles = 0
var numberOfNegativeCycles = 0
var numberOfCycles = 0
case class itemDesc(a: Int, b: Int, c: Int, d: Int, reason: String)
val example = List(ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, The values are correct), ItemDesc(14879,-14879,14879,-14894, 14879,14879,14894, The values are ok), ItemDesc(19682,-19690,-19682,19694,19690,19682,19694,The values are good),ItemDesc(5164,-5165,-5166,-6195,5165,5166,6195,The values are correct),ItemDesc(5879,5879,5879,5894,5879,5879,5879,The values are ok))
val data2 = example.map(x => getInteger(x)).filter(_ != "unknown").map(_.toString.toInt)
//println(data2)
var nCycle = findNCycle(data2)
println(nCycle)
}
def getInteger(obj: Any) = obj match {
case n: Int => obj
case _ => "unknown"
}
def findNCycle(obj: List[Int]) : Int = {
def NegativeCycles(fit: itemDesc): Int = {
if (fit.a < 0 && fit.b < 0 && fit.c < 0) || if( fit.b < 0 && fit.c < 0 && fit.d < 0)
{
numberOfNegativeCycles += 1
}
}
//println("negative cycle="+cycles)
def PositiveCycles(fit: itemDesc): Int = {
if (fit.a > 0 && fit.b > 0 && fit.c > 0) || if( fit.b > 0 && fit.c > 0 && fit.d > 0)
{
numberOfPositiveCycles += 1
}
}
//println("positive cycle="+cycles)
numberOfCycles = numberOfPositiveCycles + numberOfNegativeCycles
return numberOfCycles
}
}
For reference on the logic you can refer to- Number of Cycles from list of values, which are mix of positives and negatives in Spark and Scala
Ok this is rough but I think it does what you want. I'm sure there is a more elegant way to do the split method.
I haven't used your ItemDesc as its simpler to demonstrate the problem given the examples you gave.
object CountCycles extends App {
// No. of cycles is 1.
val example1 = List(1, 2, 3, 4, 5, 6, -15, -66)
// No. of cycles is 3.
val example2 = List(11, 22, 33, -25, -36, -43, 20, 25, 28)
// No. of cycles is 8
val example3 = List(1, 4, 82, 5, 6, -2, -12, -22, -32, 100, 102, 100, 102, 0, 0, -2, -12, -22, -32, 4, 82, 5, 6, -6, 8, -6, -6, 8, 8, -5, -6, -7, 9, 8, 6, -5, -6, -7)
def differentSign(x: Int, y: Int): Boolean =
(x < 0) != ( y < 0)
// return a list of sections
def split(l: List[Int]): List[List[Int]] =
l match {
case Nil ⇒ Nil
case h :: _ ⇒
val transition: Int = l.indexWhere(differentSign(h, _))
if (transition < 0) List(l)
else {
val (head, tail) = l.splitAt(transition)
head :: split(tail)
}
}
def count(l: List[Int]): Int = {
val pos: List[List[Int]] = split(l)
// count is the number of sections of length > 2
pos.count(_.length > 2)
}
println(count(example1)) // 1
println(count(example2)) // 3
println(count(example3)) // 8
}
This should be a working solution for the case where you have 7 items in the sample as shown in the description. If your case class changes and instead has a list of values then the implicit helper can be replaced with a simple call to the accessor
import scala.annotation.tailrec
import scala.language.implicitConversions
object CyclesCounter extends App {
val examples = List(
ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, "The values are correct"),
ItemDesc(14879,-14879,14879,-14894, 14879,14879,14894, "The values are ok"),
ItemDesc(19682,-19690,-19682,19694,19690,19682,19694,"The values are good"),
ItemDesc(5164,-5165,-5166,-6195,5165,5166,6195,"The values are correct"),
ItemDesc(5879,5879,5879,5894,5879,5879,5879,"The values are ok"))
val counter = new CycleCounter
// Add the index for more readable output
examples.zipWithIndex.foreach{ case (item, index) => println(s"Item at index $index has ${counter.cycleCount(item)} cycles")}
}
class CycleCounter {
def cycleCount(item: ItemDesc): Int = {
#tailrec
def countCycles(remainingValues: List[Int], cycles: Int): Int = {
if (remainingValues.isEmpty) cycles
else {
val headItems = {
if (remainingValues.head < 0) remainingValues.takeWhile(_ < 0)
else remainingValues.takeWhile(_ >= 0)
}
val rest = remainingValues.drop(headItems.length)
if (headItems.length > 2) countCycles(rest, cycles + 1) else countCycles(rest, cycles )
}
}
countCycles(item, 0)
}
// Helper to convert ItemDesc into a List[Int] for easier processing
implicit def itemToValueList(item: ItemDesc): List[Int] = List(item.a, item.b, item.c, item.d, item.e, item.f, item.g)
}
case class ItemDesc(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int, g: Int, reason: String)
Output from running:
Item at index 0 has 2 cycles
Item at index 1 has 1 cycles
Item at index 2 has 1 cycles
Item at index 3 has 2 cycles
Item at index 4 has 1 cycles
Hope that helps
As i read, i see that your problem is to treat the case class as a single entity and no as a list of elements and a reason. I would change the case class to one of these alternatives, first one is if the amount of elements is static (4 in this case):
case class ItemDesc(a: Int, b: Int, c: Int, d: Int, reason: String) {
lazy val getAsList = List(a,b,c,d)
}
ItemDesc(1,2,3,4,"reason").getAsList
In the second case, it can be used if the amount of elements is unbounded:
case class ItemDescAlt(reason:String, elements: Int*)
ItemDescAlt("reason", 5164,-5165,-5166,-6195,5165,5166,6195)
And like the rest i will give my custom version for calculate the number of cycles:
def getCycles(list: Seq[Int]): Int = {
def headPositive(list: Seq[Int]): Boolean = {
list.headOption.forall(_ >= 0)
}
val result = list.foldLeft((0, 0, !headPositive(list))) { //we start with a symbol diferent to the firs one
case ((numberOfCycles, cycleLength, lastWasPositive), number) => { //for each element...
val numberSign = number >= 0
val actualCycleLength = if (numberSign == lastWasPositive) { //see if the actual simbol is equal to the last one
cycleLength + 1 //in that case the length is increased
} else {
0 //in the other reset it
}
val actualNCycles = if (actualCycleLength == 2) { //if the actual length is equal to to
numberOfCycles + 1 //it is a proper new cycle
} else {
numberOfCycles // no new cycles
}
(actualNCycles, actualCycleLength, numberSign) //return the actual state
}
}
result._1 //get the final number of cycles
}
If you already have a solution for List, you can convert any case class into a List using productIterator:
scala> case class X(a:Int, b:Int, c:String)
defined class X
scala> val x = X(1,2,"a")
x: X = X(1,2,a)
scala> x.productIterator.toList
res1: List[Any] = List(1, 2, a)
The main problem is that you get back a List[Any] so you might have to do more work to get a List[Int]
I have to write a method "all()" which returns a list of tuples; each tuple will contain the row, column and set relevant to a particular given row and column, when the function meets a 0 in the list. I already have written the "hyp" function which returns the set part I need, eg: Set(1,2).
I am using a list of lists:
| 0 | 0 | 9 |
| 0 | x | 0 |
| 7 | 0 | 8 |
If Set (1,2) are referring to the cell marked as x, all() should return: (1,1, Set(1,2))
where 1,1 are the index of the row and column.
I wrote this method by using zipWithIndex but I can't use this function. Is there any simpler way how to access an index as in this case? Thanks in advance
Code:
def all(): List[(Int, Int, Set[Int])] =
{
puzzle.list.zipWithIndex flatMap
{
rowAndIndex =>
rowAndIndex._1.zipWithIndex.withFilter(_._1 == 0) map
{
colAndIndex =>
(rowAndIndex._2, colAndIndex._2, hyp(rowAndIndex._2, colAndIndex._2))
}
}
}
The (_._1 == 0 ) is because the function has to return the (Int,Int, Set()) only when it finds a 0 in the grid
The all function can be simplified as this:
// Given a list of list
puzzle.list = List(List(0, 0, 9), List(0, 5, 0), List(7, 0, 8))
for {
(row, rIndex) <- puzzle.list.zipWithIndex // List of (row, index)
// List( (List(0,0,9), 0) ...
(col, cIndex) <- row.zipWithIndex; // List of (col, index)
// List( (0,0), (0,1), (9, 2) ...
if (col == 0) // keep only col with 0
} yield (rIndex, cIndex, hyp(rIndex, cIndex))
I have a functions that returns cases from a table that match specific strings.
Once I get all the cases that match those strings, I need to search each case (which is its own list) for specific strings and do a Which command. But all I know how to do is turn the whole big list of lists into one string, and then I only get one result (when I need a result for each case).
UC#EncodeTable;
EncodeTable[id_?PersonnelQ, f___] :=
Cases[#,
x_List /;
MemberQ[x,
s_String /;
StringMatchQ[
s, ("*ah*" | "*bh*" | "*gh*" | "*kf*" |
"*mn*"), IgnoreCase -> True]], {1}] &#
Cases[MemoizeTable["PersonnelTable.txt"], {_, id, __}]
That function is returning cases from the table
Which[(StringMatchQ[
ToString#
EncodeTable[11282], ("*bh*" | "*ah*" |
"*gh*" ), IgnoreCase -> True]) == True, 1,
(StringMatchQ[
ToString#
EncodeTable[11282], ("*bh*" | "*ah*" |
"*gh*" ), IgnoreCase -> True]) == False, 0]
That function is SUPPOSED to return a 1 or 0 for each case returned by the first function, but I don't know how to search within lists without making them all one string and return a result for each list.
Well, you probaby want Map, but it's hard to say without seeing what the structure of the data to be operated upon is. Perhaps you can provide an example.
EDIT: In the comment, an example result was given as
dat = {{204424, 11111, SQLDateTime[{1989, 4, 4, 0, 0, 0.}], Null,
"Parthom, Mary, MP", Null, 4147,
"T-00010 AH BH UI", {"T-00010 AH BH UI", "M-14007 LL GG",
"F-Y3710 AH LL UI GG"}, "REMOVED."}, {2040, 11111,
SQLDateTime[{1989, 4, 13, 0, 1, 0.}], Null, "KEVIN, Stevens, STK",
Null, 81238,
"T-00010 ah gh mn", {"T-00010 mn", "M-00100 dd", "P-02320 sd",
"M-14003 ed", "T-Y8800 kf", "kj"}}};
(actually the example had a syntax error so I fixed it in what I hope is the right way).
Now, if I define a function
func = Which[(StringMatchQ[#[[8]], ("*bh*" | "*ah*" | "*gh*"),
IgnoreCase -> True]) == True, 1, True, 0] &;
(note the second condition to be matched may be written as True, see the documentation of Which) which does this
func[dat[[1]]]
(*
-> 1
*)
(note that I've slightly changed func from what you have, in order for it to do what I assume you wanted it to actually do). This can then be applied to dat, of which the elements have the form you gave, as follows:
Map[func, dat]
(*
-> {1, 1}
*)
I'm not sure if this is what you want, I did my best guessing.
EDIT2: In response to the comment about the position of the element to be matched being variable, here is one way:
ClearAll[funcel]
funcel[p_String] :=
Which[StringMatchQ[p, ("*bh*" | "*ah*" | "*gh*"),
IgnoreCase -> True], 1, True, 0];
funcel[___] := 0;
ClearAll[func];
func[lst_List] := Which[MemberQ[Map[funcel, lst], 1], 1, True, 0]
so that
Map[func, dat]
gives {1,1}