অপরিবর্তনীয় তালিকা থেকে একটি উপাদানকে "অপসারণ" করার একটি অহঙ্কারী স্কেল উপায় কী?


86

আমার একটি তালিকা রয়েছে, এতে এমন উপাদান থাকতে পারে যা সমান হিসাবে তুলনা করবে। আমি অনুরূপ তালিকা চাই তবে একটি উপাদান মুছে ফেলাতে চাই। সুতরাং (এ, বি, সি, বি, ডি) থেকে আমি উদাহরণস্বরূপ (এ, সি, বি, ডি) পেতে কেবল একটি বি "অপসারণ" করতে সক্ষম হতে চাই। ফলাফলের উপাদানগুলির ক্রম কোনও বিষয় নয়।

আমার ওয়ার্কিং কোড রয়েছে, স্কালায় লিস্প-অনুপ্রাণিত ভাবে লেখা। এটি করার মতো আরও কোনও মুশকিল উপায় আছে?

প্রসঙ্গটি এমন একটি কার্ড গেম যেখানে দুটি ডেক স্ট্যান্ডার্ড কার্ড প্লে হয়, সুতরাং ডুপ্লিকেট কার্ডগুলি থাকতে পারে তবে এখনও একবারে একটি খেলেছে।

def removeOne(c: Card, left: List[Card], right: List[Card]): List[Card] = {
  if (Nil == right) {
    return left
  }
  if (c == right.head) {
    return left ::: right.tail
  }
  return removeOne(c, right.head :: left, right.tail)
}

def removeCard(c: Card, cards: List[Card]): List[Card] = {
  return removeOne(c, Nil, cards)
}

ফলাফলের তালিকার ক্রম এই নির্দিষ্ট ক্ষেত্রে গুরুত্বপূর্ণ নয় বলে একটি নোট যুক্ত করেছেন।
গ্যাভিলান কমুন

সুতরাং List[Card]এই প্রশ্নে একজন খেলোয়াড়ের হাত?
কেন ব্লুম

@ কেন ব্লুম, হ্যাঁ এটাই ঠিক একজন খেলোয়াড়ের হাত।
গ্যাভিলান কমুন

আপনি জানেন, আমি এই জাতীয় প্রশ্নের জন্য কিছুক্ষণ অনুসন্ধান করেছি, আবার একই প্রশ্নটি পোস্ট করেছিলাম, তারপরে যখন আমি ব্রাউজ করছি এবং লোকেরা আমার উত্তর দেওয়ার অপেক্ষায় ছিল তখন এটি পাওয়া গেল। অনুমান করুন এখন আমার নিজের প্রশ্নটি নকল হিসাবে বন্ধ করার জন্য ভোট দেওয়া উচিত। ;-)
জো কার্নাহান

ক্লোজারের জন্য এই প্রশ্ন: স্ট্যাকওভারফ্লো.
গ্যাভিলান কমুন

উত্তর:


147

আমি উপরের উত্তরগুলিতে এই সম্ভাবনাটি দেখিনি, তাই:

scala> def remove(num: Int, list: List[Int]) = list diff List(num)
remove: (num: Int,list: List[Int])List[Int]

scala> remove(2,List(1,2,3,4,5))
res2: List[Int] = List(1, 3, 4, 5)

সম্পাদনা করুন:

scala> remove(2,List(2,2,2))
res0: List[Int] = List(2, 2)

জাদুর মত :-).


18
সুন্দর! কেবলমাত্র একটি উপাদান মুছে ফেলা হয়েছে তা পরিষ্কার করতে আমি তালিকায় আরও 2 যুক্ত করব।
ফ্রাঙ্ক এস থমাস

40

আপনি filterNotপদ্ধতিটি ব্যবহার করতে পারেন ।

val data = "test"
list = List("this", "is", "a", "test")
list.filterNot(elm => elm == data)

22
এটি "পরীক্ষার" সমান সমস্ত উপাদান সরিয়ে ফেলবে - যা জিজ্ঞাসা করা হয় তা নয়;)
Y Octsǝla

4
আসলে এটি আপনার যা প্রয়োজন ঠিক তা করবে। এটি "পরীক্ষার" সমান নয় এমনগুলি বাদ দিয়ে তালিকা থেকে সমস্ত উপাদান ফিরিয়ে দেবে। মনোযোগ দিন যে এটি ফিল্টারনট
বিটিবিভয়

14
মূল প্রশ্নটি ছিল কীভাবে একটি একক দৃষ্টান্ত সরিয়ে ফেলা যায়। সমস্ত দৃষ্টান্ত না।
ty1824

@ সোরেন ম্যাথিয়াসেন যদি আমি ভ্যালু ডেটা = সেক ("পরীক্ষা", "ক") এর মতো সিকোয়েন্সের মতো একাধিক উপাদানগুলি ফিল্টার করতে চাই তবে এটি কীভাবে করবেন?
বিডিজিনিয়ার

18

আপনি এটি চেষ্টা করতে পারেন:

scala> val (left,right) = List(1,2,3,2,4).span(_ != 2)
left: List[Int] = List(1)
right: List[Int] = List(2, 3, 2, 4)

scala> left ::: right.tail                            
res7: List[Int] = List(1, 3, 2, 4)

এবং পদ্ধতি হিসাবে:

def removeInt(i: Int, li: List[Int]) = {
   val (left, right) = li.span(_ != i)
   left ::: right.drop(1)
}

4
এটি উল্লেখযোগ্য যে left ::: right.drop(1)এটি যদি বিবৃতি দিয়ে সংক্ষেপে কম হয় isEmpty
রেক্স কের

4
ধন্যবাদ, .ড (1) ওভার টেইল বা তার বিপরীতে কোন পছন্দ আছে?
গ্যাভিলান কমুন

8
@James Petry - আপনি কল যদি tailএকটি খালি তালিকায় আপনি একটি ব্যতিক্রম পাবেন: scala> List().tail java.lang.UnsupportedOperationException: tail of empty listdrop(1)একটি খালি তালিকায় তবে একটি খালি তালিকা দেয়।
ফ্র্যাঙ্ক এস থমাস

4
tailতালিকাটি ফাঁকা থাকলে (যেমন কোনও নেই head) ব্যতিক্রম ছুঁড়ে । drop(1)খালি তালিকায় অন্য একটি খালি তালিকা পাওয়া যায়।
রেক্স কের

8

দুর্ভাগ্যক্রমে, সংগ্রহের শ্রেণিবিন্যাস কিছুটা গণ্ডগোলের মধ্যে পরিণত -হয়েছিল List। কারণ ArrayBufferএটি আপনার আশা মতো ঠিক কাজ করে:

scala> collection.mutable.ArrayBuffer(1,2,3,2,4) - 2
res0: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 3, 2, 4)

তবে, দুঃখের বিষয়, Listএকটি filterNotস্টাইল বাস্তবায়ন শেষ হয়েছে এবং এইভাবে "ভুল জিনিস" করে এবং আপনাকে অবহেলা করার সতর্কতা ছুড়ে দেয় (যথেষ্ট বুদ্ধিমান, যেহেতু এটি প্রকৃতপক্ষে filterNotইঙ্গিতপ্রাপ্ত):

scala> List(1,2,3,2,4) - 2                          
warning: there were deprecation warnings; re-run with -deprecation for details
res1: List[Int] = List(1, 3, 4)

সুতরাং যুক্তিযুক্তভাবে করণীয় সবচেয়ে সহজ কাজটি হ'ল Listএকটি সংগ্রহে রূপান্তর করা যা এই কাজটি করে এবং তারপরে আবারও রূপান্তরিত হয়:

import collection.mutable.ArrayBuffer._
scala> ((ArrayBuffer() ++ List(1,2,3,2,4)) - 2).toList
res2: List[Int] = List(1, 3, 2, 4)

বিকল্পভাবে, আপনি যে কোডটি পেয়েছেন সেটির যুক্তি রাখতে পারলেও শৈলীটি আরও মূর্তিযুক্ত করতে পারেন:

def removeInt(i: Int, li: List[Int]) = {
  def removeOne(i: Int, left: List[Int], right: List[Int]): List[Int] = right match {
    case r :: rest =>
      if (r == i) left.reverse ::: rest
      else removeOne(i, r :: left, rest)
    case Nil => left.reverse
  }
  removeOne(i, Nil, li)
}

scala> removeInt(2, List(1,2,3,2,4))
res3: List[Int] = List(1, 3, 2, 4)

removeInt(5,List(1,2,6,4,5,3,6,4,6,5,1))ফলন List(4, 6, 2, 1, 3, 6, 4, 6, 5, 1)। আমি মনে করি এটি আপনি যা চেয়েছিলেন তা নয়।
কেন ব্লুম

@ কেন ব্লুম - আসলেই। এটি মূল অ্যালগরিদমের একটি ত্রুটি, যা আমি যথেষ্ট চিন্তা না করেই অনুলিপি করেছি। এখনই স্থির।
রেক্স কের

প্রশ্নটিতে আরও একটি বাদ, কারণ আদেশটি আমার নির্দিষ্ট ক্ষেত্রে গুরুত্বপূর্ণ নয়। অর্ডার-সংরক্ষণ সংস্করণ দেখতে ভাল, ধন্যবাদ।
গ্যাভিলান কমুন

@ রেক্স: 'ফিল্টারনট "" ভুল জিনিস "" বলতে কী বোঝায়? এটি সমস্ত ঘটনাগুলি সরিয়ে দিচ্ছে? এবং কেন এটি অবমূল্যায়নের সতর্কতা ছুঁড়ে ফেলে? ধন্যবাদ
টিও

4
@ টিটিও - এটি সমস্ত ঘটনাগুলি সরিয়ে দেয় (যা এখানে পছন্দসই নয়) এবং এটি অবহেলা করা হয়েছে কারণ এটি যুক্তিযুক্তভাবে ভেঙে গেছে (বা সম্ভবত কাঙ্ক্ষিত আচরণটি অস্পষ্ট - উভয়ইভাবেই এটি ২.৯ এ অবমানিত হয়ে ২.১০ এ চলে গেছে)।
রেক্স কের


2

কেমন

def removeCard(c: Card, cards: List[Card]) = {
  val (head, tail) = cards span {c!=}   
  head ::: 
  (tail match {
    case x :: xs => xs
    case Nil => Nil
  })
}

যদি আপনি দেখতে পান returnতবে কিছু ভুল আছে।


4
এটি তার যা করতে চায় তা করে না, যা কেবল প্রথম উদাহরণটি সরিয়ে ফেলতে হবেc
কেন ব্লুম

4
এটি সমস্ত কার্ড সরিয়ে ফেলবে c, তবে কেবল প্রথমে অপসারণ করা উচিত।
দশশি

প্রশ্নগুলি আরও মনোযোগ সহকারে আমার পড়া উচিত! আমার উত্তর সংশোধন।
ইউজিন ইয়োকোটা

"যদি আপনি ফিরে দেখেন তবে কিছু ভুল আছে for" এটি নিজেই একটি অত্যন্ত গুরুত্বপূর্ণ "আইডেম্যাটিক স্কাল" পাঠ।
জো কার্নাহান


1

একটি সম্ভাব্য সমাধান হিসাবে আপনি প্রথম উপযুক্ত উপাদানটির সূচক খুঁজে পেতে পারেন এবং তারপরে এই সূচীতে উপাদানটি সরিয়ে ফেলতে পারেন:

def removeOne(l: List[Card], c: Card) = l indexOf c match {
    case -1 => l
    case n => (l take n) ++ (l drop (n + 1))
}

আমার উত্তরটি spanএকই জিনিসটি ব্যবহার করে দেখুন ।
কেন ব্লুম

0

ভাঁজ ব্যবহার করে এটি কীভাবে করা যায় সে সম্পর্কে আরও একটি চিন্তা:

def remove[A](item : A, lst : List[A]) : List[A] = {
    lst.:\[List[A]](Nil)((lst, lstItem) => 
       if (lstItem == item) lst else lstItem::lst )
}

0

জেনেরিক টেল পুনরাবৃত্তি সমাধান:

def removeElement[T](list: List[T], ele: T): List[T] = {
    @tailrec
    def removeElementHelper(list: List[T],
                            accumList: List[T] = List[T]()): List[T] = {
      if (list.length == 1) {
        if (list.head == ele) accumList.reverse
        else accumList.reverse ::: list
      } else {
        list match {
          case head :: tail if (head != ele) =>
            removeElementHelper(tail, head :: accumList)
          case head :: tail if (head == ele) => (accumList.reverse ::: tail)
          case _                             => accumList
        }
      }
    }
    removeElementHelper(list)
  }


-4
object HelloWorld {

    def main(args: Array[String]) {

        var months: List[String] = List("December","November","October","September","August", "July","June","May","April","March","February","January")

        println("Deleting the reverse list one by one")

        var i = 0

        while (i < (months.length)){

            println("Deleting "+months.apply(i))

            months = (months.drop(1))

        }

        println(months)

    }

}

আপনি কি দয়া করে কিছু ব্যাখ্যা (মন্তব্য, বিবরণ) যুক্ত করতে পারেন যাতে এটি প্রশ্নের উত্তর কীভাবে দেয়?
rjp

4
1. এই প্রশ্নটি 5 বছর আগে জিজ্ঞাসা করা হয়েছিল এবং উত্তর দেওয়া হয়েছিল। ২. ওপিতে "আইডোমেটিক" স্কাল চেয়েছিল। 2 varটি এবং একটি whileলুপ ব্যবহার করা মূর্তিযুক্ত স্ক্যালাল নয়।
jwvh
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.