একটি স্কালা তালিকা তৈরি করার পছন্দের উপায়


117

স্কালায় একটি অপরিবর্তনীয় তালিকা তৈরির বিভিন্ন উপায় রয়েছে (নীচে স্বীকৃত উদাহরণ কোড দেখুন)। আপনি একটি পরিবর্তনীয় তালিকার বাফার ব্যবহার করতে পারেন, একটি varতালিকা তৈরি করতে পারেন এবং এটি সংশোধন করতে পারেন, একটি লেজ পুনরাবৃত্ত পদ্ধতি ব্যবহার করতে পারেন , এবং সম্ভবত অন্যরা যা আমি জানিনা।

সহজাতভাবে, আমি তালিকার বাফারটি ব্যবহার করি, তবে এটি করার পক্ষে আমার কোনও ভাল কারণ নেই। তালিকা তৈরির জন্য কি পছন্দের বা আইডোমেটিক পদ্ধতি আছে, বা এমন পরিস্থিতি রয়েছে যা অন্য পদ্ধতির জন্য এক পদ্ধতির জন্য সবচেয়ে ভাল?

import scala.collection.mutable.ListBuffer

// THESE are all the same as: 0 to 3 toList.
def listTestA() ={
    var list:List[Int] = Nil

    for(i <- 0 to 3) 
        list = list ::: List(i)
    list
}


def listTestB() ={
    val list = new ListBuffer[Int]()

    for (i <- 0 to 3) 
        list += i
    list.toList
}


def listTestC() ={
    def _add(l:List[Int], i:Int):List[Int] = i match {
        case 3 => l ::: List(3)
        case _ => _add(l ::: List(i), i +1)
    }
    _add(Nil, 0)
}

উত্তর:


108

ListBufferএকটি পরিবর্তনীয় তালিকা যা ধ্রুবক সময় সংযোজন, এবং একটি এ ধ্রুবক সময় রূপান্তর আছে List

List অপরিবর্তনীয় এবং ধ্রুবক সময় প্রস্তুতি এবং লিনিয়ার সময় সংযোজন আছে।

আপনি কীভাবে আপনার তালিকা তৈরি করবেন তা নির্ভর করে আপনি সেই তালিকাটি এবং যে ক্রমে উপাদানগুলি তৈরি করার জন্য এটি পেয়েছেন সেই তালিকাটি ব্যবহার করবেন on

উদাহরণস্বরূপ, আপনি যদি উপাদানগুলি কখন ব্যবহার করতে যাচ্ছেন তার বিপরীতে ক্রমে পান তবে আপনি কেবল একটি ব্যবহার করতে পারেন Listএবং প্রিপেন্ডস ব্যবহার করতে পারেন । আপনি একটি লেজ-পুনরাবৃত্তি ফাংশন foldLeft, বা অন্য কিছু সঙ্গে এটি করবেন কিনা আসলেই প্রাসঙ্গিক নয়।

আপনি যদি সেগুলি একই ক্রমে ব্যবহার করেন এমন উপাদানগুলি পান ListBufferতবে পারফরম্যান্স সমালোচিত হলে সম্ভবত একটি পছন্দনীয় পছন্দ।

তবে, আপনি যদি কোনও গুরুত্বপূর্ণ পথে না যান এবং ইনপুটটি যথেষ্ট পরিমাণে কম থাকে তবে আপনি সর্বদা reverseতালিকাটি পরে, বা ন্যায়সঙ্গত foldRightবা reverseইনপুটটি করতে পারেন যা লিনিয়ার সময়।

আপনি যা করবেন না তা হ'ল একটি ব্যবহার Listকরুন এবং এতে যুক্ত হন। এটি আপনাকে কেবল প্রিপেন্ডিং এবং শেষে বিপরীতমুখী করার চেয়ে আরও খারাপ কার্য সম্পাদন করবে।


What you DON'T do is use a List and append to itএটি কি নতুন তালিকা তৈরি হওয়ার কারণে? অন্যদিকে, একটি প্রিপেন্ড অপারেশন ব্যবহার করে কোনও নতুন তালিকা তৈরি হবে না?
কেভিন মেরেডিথ

2
নিবন্ধন করুন পরিশিষ্টটি হ'ল (এন), প্রিপেন্ড হ'ল ও (1)।
ড্যানিয়েল সি সোব্রাল

@pgoggijr এটি সত্য নয়। প্রথমত, কোথাও কোনও "পরিবর্তন" নেই, কারণ তা পরিবর্তনযোগ্য নয়। একটি ট্র্যাভারসাল প্রয়োজনীয় কারণ সমস্ত উপাদান অনুলিপি করতে হয়, ঠিক তাই শেষ উপাদানটির একটি অনুলিপি পরিবর্তে একটি নতুন উপাদানকে নির্দেশ করা যায় Nil। দ্বিতীয়ত, প্রিপেন্ডে কোনও ধরণের কোনও অনুলিপি নেই: বিদ্যমান উপাদানটির দিকে ইঙ্গিত করে একটি উপাদান তৈরি করা হয় এবং এটিই।
ড্যানিয়েল সি


22

আহমম .. এগুলি আমার কাছে খুব জটিল মনে হচ্ছে। আমি প্রস্তাব দিতে পারি

def listTestD = (0 to 3).toList

অথবা

def listTestE = for (i <- (0 to 3).toList) yield i

উত্তরের জন্য ধন্যবাদ, তবে প্রশ্নটি হ'ল অ তুচ্ছ মামলায় আপনি কী করবেন। আমি কোডে একটি মন্তব্য দিয়েছিলাম যে তারা সমস্ত 0 থেকে 3 টি তালিকার সমতুল্য ছিল।
অগপলফাল

উফ, আফসোস তাহলে! সত্যি বলতে, আমি কখনই লিস্টবফার ব্যবহার করি না।
আলেকজান্ডার আজারভ

5

আপনি সাধারণত কোনও ভার্সেস বাদ দিয়ে স্কেলে অপরিবর্তনীয়তার দিকে মনোনিবেশ করতে চান। পাঠযোগ্যতা এখনও আপনার সহকর্মীর পক্ষে গুরুত্বপূর্ণ:

চেষ্টা করুন:

scala> val list = for(i <- 1 to 10) yield i
list: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

আপনার সম্ভবত বেশিরভাগ ক্ষেত্রে কোনও তালিকায় রূপান্তর করার প্রয়োজনও নেই :)

ইনডেক্সড সিকের আপনার প্রয়োজনীয় সমস্ত কিছু থাকবে:

অর্থাৎ আপনি এখন সেই সূচিপত্রটিতে কাজ করতে পারেন:

scala> list.foldLeft(0)(_+_)
res0: Int = 55

এনবি Vectorএখন ডিফল্ট Seqবাস্তবায়নও।
কনার ডয়েল

2

আমি সর্বদা তালিকা পছন্দ করি এবং আমি "বোঝার জন্য" আগে "ভাঁজ / হ্রাস" ব্যবহার করি। তবে নেস্টেড "ভাঁজ" প্রয়োজন হলে "বোঝার জন্য" অগ্রাধিকার দেওয়া হয়। "ভাঁজ / হ্রাস / for" ব্যবহার করে যদি আমি কাজটি সম্পাদন করতে না পারি তবে পুনরাবৃত্তি হ'ল শেষ অবলম্বন।

সুতরাং আপনার উদাহরণের জন্য, আমি করব:

((0 to 3) :\ List[Int]())(_ :: _)

আমি করার আগে:

(for (x <- 0 to 3) yield x).toList

দ্রষ্টব্য: আমি "_" এস এর ক্রমের কারণে এখানে "ফোল্ড লেফট (/ :)" এর পরিবর্তে "ফোল্ডারাইট (: \)" ব্যবহার করি। স্ট্যাকওভারফ্লো এক্সেক্সশনটি ছুঁড়ে না এমন কোনও সংস্করণের জন্য, পরিবর্তে "ফোল্ড লেফট" ব্যবহার করুন।


18
আমি দৃ strongly়ভাবে একমত না; আপনার পছন্দসই ফর্মটি কেবল লাইন শব্দের মতো দেখাচ্ছে।
ম্যাট আর

14
আমি কি করব? আমি ১৯৯৯ সালে প্রথম হাস্কেল শিখেছি এবং কয়েক বছর ধরে স্কালায় ছড়িয়ে পড়েছি। আমার মনে হয় ভাঁজগুলি দুর্দান্ত, তবে কোনও নির্দিষ্ট পরিস্থিতিতে যদি ভাঁজ প্রয়োগের জন্য বিরাম চিহ্নগুলির একটি গুপ্ত স্ট্রিং রচনার প্রয়োজন হয়, আমি আলাদা পদ্ধতির বিষয়টি বিবেচনা করব।
ম্যাট আর

11
@ ম্যাট আর: আমি সম্মত এটি অত্যধিক করার মতো জিনিস রয়েছে এবং এটি তাদের মধ্যে একটি।
রাইগুয়ে

8
@ ওয়াল্টারচ্যাং আমি সেই সমস্ত ইমোটিকনের চেহারা পছন্দ করি। এক মিনিট অপেক্ষা করুন, এটা কি কোড? : পি
ডেভিড জে।

4
একে ডাকতে ন্যায্য ((0 to 3) :\ List[Int]())(_ :: _)emoticode?
ডেভিড জে।


2

দ্রষ্টব্য: এই উত্তরটি স্কালার একটি পুরানো সংস্করণের জন্য লেখা।

স্কালার সংগ্রহের ক্লাসগুলি স্কেলা ২.৮ হিসাবে নতুনভাবে নকশিত হতে চলেছে, সুতরাং খুব শীঘ্রই আপনি তালিকা তৈরি করার পদ্ধতিটি পরিবর্তন করতে প্রস্তুত থাকুন।

তালিকা তৈরির সামঞ্জস্যপূর্ণ উপায় কী? আমি এখনও ২.৮ ডক না পড়ার পরে আমার কোনও ধারণা নেই।

সংগ্রহ ক্লাসের প্রস্তাবিত পরিবর্তনগুলি বর্ণনা করে একটি পিডিএফ নথি


2
বেশিরভাগ পরিবর্তনগুলি জিনিসগুলি অভ্যন্তরীণভাবে প্রয়োগ করা হয় এবং ভবিষ্যদ্বাণীগুলির মতো উন্নত জিনিসগুলিতে হয়। আপনি কীভাবে একটি তালিকা তৈরি করবেন তা প্রভাবিত হয় না।
মার্কাস ডাউনিং

ঠিক আছে, এটি জেনে রাখা ভাল। আপনি সংগ্রহে.জেসিএল প্যাকেজে কোনও শ্রেণি ব্যবহার করলে আপনিও ক্ষতিগ্রস্থ হবেন।
আন্দ্রে লাসল্লো

1

একটি নতুন স্কালার বিকাশকারী হিসাবে আমি উপরে প্রস্তাবিত পদ্ধতির সাথে তালিকা তৈরির সময়টি পরীক্ষা করতে একটি ছোট পরীক্ষা লিখেছি। দেখে মনে হচ্ছে (পি (- 0 থেকে x) ফলন পি) জন্য দ্রুততম পদ্ধতির তালিকাবদ্ধ করুন।

import java.util.Date
object Listbm {

  final val listSize = 1048576
  final val iterationCounts = 5
  def getCurrentTime: BigInt = (new Date) getTime

  def createList[T] ( f : Int => T )( size : Int ): T = f ( size )

  // returns function time execution
  def experiment[T] ( f : Int => T ) ( iterations: Int ) ( size :Int ) : Int  = {

    val start_time = getCurrentTime
    for ( p <- 0 to iterations )  createList ( f ) ( size )
    return (getCurrentTime - start_time) toInt

  }

  def printResult ( f:  => Int ) : Unit = println ( "execution time " + f  )

  def main( args : Array[String] ) {


    args(0) match {

      case "for" =>  printResult ( experiment ( x => (for ( p <- ( 0 to x ) ) yield p) toList  ) ( iterationCounts ) ( listSize ) )
      case "range"  =>  printResult ( experiment ( x => ( 0 to x ) toList ) ( iterationCounts ) ( listSize ) )
      case "::" => printResult ( experiment ( x => ((0 to x) :\ List[Int]())(_ :: _) ) ( iterationCounts ) ( listSize ) )
      case _ => println ( "please use: for, range or ::\n")
    }
  }
}

0

সংগ্রহ.ব্রেকআউট ব্যবহার করে এমন একটি উদাহরণ

scala> val a : List[Int] = (for( x <- 1 to 10 ) yield x * 3)(collection.breakOut)
a: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)

scala> val b : List[Int] = (1 to 10).map(_ * 3)(collection.breakOut)
b: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)

0

স্ট্রিংয়ের একটি তালিকা তৈরি করতে, নিম্নলিখিতটি ব্যবহার করুন:

val l = List("is", "am", "are", "if")

1
এই পুরানো (10 বছর) কোনও প্রশ্নের উত্তর দেওয়ার সময় এবং প্রচুর বিদ্যমান উত্তরগুলির সাথে (9), কেন আপনার উত্তরটি অন্য সমস্তের থেকে আলাদা কেন তা বোঝানো ভাল অনুশীলন। যেমনটি রয়েছে, দেখে মনে হচ্ছে আপনি প্রশ্নটি বুঝতে পারেন নি।
jwvh
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.