मुझे ऑब्जेक्ट्स की एक सूची मिली है List[Object]
जो सभी एक ही कक्षा से तत्काल हैं। इस वर्ग में एक फ़ील्ड है जो अद्वितीय Object.property
होना चाहिए। वस्तुओं की सूची को फिर से शुरू करने और एक ही संपत्ति के साथ सभी वस्तुओं (लेकिन पहले) को हटाने का सबसे साफ तरीका क्या है?स्कैला: ऑब्जेक्ट्स की सूची में डुप्लीकेट हटाएं
उत्तर
list.groupBy(_.property).map(_._2.head)
स्पष्टीकरण: समूह द्वारा विधि एक फ़ंक्शन स्वीकार करती है जो समूह के लिए किसी तत्व को कुंजी में परिवर्तित करती है। _.property
elem: Object => elem.property
के लिए सिर्फ लघुरूप है (संकलक एक अद्वितीय नाम उत्पन्न करता है, x$1
जैसा कुछ)। तो अब हमारे पास नक्शा Map[Property, List[Object]]
है। Map[K,V]
Traversable[(K,V)]
बढ़ाता है। तो इसे एक सूची की तरह घुमाया जा सकता है, लेकिन तत्व एक tuple हैं। यह जावा के Map#entrySet()
के समान है। नक्शा विधि प्रत्येक तत्व को पुन: सक्रिय करके और इसमें एक फ़ंक्शन लागू करके एक नया संग्रह बनाता है। इस मामले में फ़ंक्शन _._2.head
है जो elem: (Property, List[Object]) => elem._2.head
के लिए शॉर्टेंड है। _2
सिर्फ ट्यूपल का एक तरीका है जो दूसरा तत्व देता है। दूसरा तत्व की सूची [वस्तु] और head
पहला तत्व
रिटर्न परिणाम प्राप्त करने के लिए एक प्रकार आप चाहते हैं हो रहा है:
import collection.breakOut
val l2: List[Object] = list.groupBy(_.property).map(_._2.head)(breakOut)
संक्षिप्त व्याख्या करने के लिए, map
वास्तव में दो तर्क, एक समारोह और एक उम्मीद ऑब्जेक्ट जिसका उपयोग परिणाम बनाने के लिए किया जाता है। पहले कोड स्निपेट में आपको दूसरा मान नहीं दिखाई देता है क्योंकि इसे निहित के रूप में चिह्नित किया जाता है और इसलिए कंपाइलर द्वारा पूर्वनिर्धारित मानों की सूची से प्रदान किया जाता है। नतीजा आमतौर पर मैप किए गए कंटेनर से प्राप्त होता है। यह आमतौर पर एक अच्छी बात है। सूची पर नक्शा सूची लौटाएगा, ऐरे पर नक्शा ऐरे वापस लौटाएगा। इस मामले में, हम कंटेनर को व्यक्त करना चाहते हैं जिसके परिणामस्वरूप हम चाहते हैं। यह वह जगह है जहां ब्रेकऑट विधि का उपयोग किया जाता है। यह वांछित परिणाम प्रकार को देखकर एक निर्माता (वह चीज जो परिणाम बनाता है) बनाता है। यह एक सामान्य तरीका है और संकलक इसके जेनेरिक प्रकार infers क्योंकि हम स्पष्ट रूप से l2 टाइप किया List[Object]
होने के लिए या, क्रम बनाए रखने के (यह मानते हुए Object#property
प्रकार Property
की है):
list.foldRight((List[Object](), Set[Property]())) {
case (o, [email protected](objects, props)) =>
if (props(o.property)) cum else (o :: objects, props + o.property))
}._1
foldRight
एक विधि है कि एक प्रारंभिक परिणाम को स्वीकार करता है और एक ऐसा फ़ंक्शन जो तत्व को स्वीकार करता है और एक अद्यतन परिणाम देता है। विधि प्रत्येक तत्व को पुन: लागू करती है, प्रत्येक तत्व को फ़ंक्शन को लागू करने और अंतिम परिणाम लौटने के परिणामस्वरूप परिणाम अपडेट करती है। हम दाएं से बाएं (foldLeft
के साथ बाएं से दाएं के बजाय) जाते हैं क्योंकि हम objects
पर आगे बढ़ रहे हैं - यह ओ (1) है, लेकिन संलग्न करना ओ (एन) है। यहां अच्छी स्टाइल का भी निरीक्षण करें, हम तत्व निकालने के लिए एक पैटर्न मैच का उपयोग कर रहे हैं।
इस मामले में, प्रारंभिक परिणाम एक खाली सूची और एक सेट की एक जोड़ी (tuple) है। सूची वह परिणाम है जिसमें हम रुचि रखते हैं और सेट का उपयोग यह जानने के लिए किया जाता है कि हम किन संपत्तियों का सामना कर चुके हैं। प्रत्येक यात्रा में हम जाँच करता है, तो सेट props
पहले से ही प्रॉपर्टी वाला (स्काला में, obj(x)
obj.apply(x)
लिए अनुवाद किया है। Set
में, विधि apply
def apply(a: A): Boolean
है। यही कारण है कि है, एक तत्व स्वीकार करता है और सही/गलत रिटर्न यदि वह मौजूद है या नहीं)। यदि संपत्ति मौजूद है (पहले से ही सामना किया गया है), परिणाम के रूप में वापस आ गया है।अन्यथा परिणाम वस्तु (o :: objects
) को रोकने के लिए अद्यतन किया जाता है और संपत्ति दर्ज की गई है (props + o.property
)
अद्यतन:
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
class RichCollection[A, Repr](xs: IterableLike[A, Repr]){
def distinctBy[B, That](f: A => B)(implicit cbf: CanBuildFrom[Repr, A, That]) = {
val builder = cbf(xs.repr)
val i = xs.iterator
var set = Set[B]()
while (i.hasNext) {
val o = i.next
val b = f(o)
if (!set(b)) {
set += b
builder += o
}
}
builder.result
}
}
implicit def toRich[A, Repr](xs: IterableLike[A, Repr]) = new RichCollection(xs)
उपयोग करने के लिए:
scala> list.distinctBy(_.property)
res7: List[Obj] = List(Obj(1), Obj(2), Obj(3))
@andreypopp एक सामान्य तरीका चाहते थे यह भी ध्यान रखें कि यह एक निर्माता है क्योंकि हम एक निर्माता का उपयोग कर रहे हैं। क्या तुम सच में बड़े सूचियों है, तो आप एक नियमित रूप से सेट और बेंचमार्क प्रदर्शन के बजाय एक परिवर्तनशील HashSet उपयोग कर सकते हैं।
list.filterNot{ var set = Set[Property]()
obj => val b = set(obj.property); set += obj.property; b}
हालांकि यह आंतरिक रूप से एक वर, मुझे लगता है कि यह समझना महत्वपूर्ण है और foldLeft-समाधान की तुलना में पढ़ने में आसान है का उपयोग करता है:
भयानक होगा यदि आप त्वरित स्पष्टीकरण प्रदान कर सकते हैं। मुझे लगता है कि स्कैला पर्याप्त रूप से नया है कि हर कोई इसे तुरंत समझ नहीं पाएगा। –
विशेष रूप से, क्या 'इस संदर्भ में क्या _2' करता है? –
@Sudhir: _1 और _2 तरीकों कि एक टपल के पहले और दूसरे तत्व लौट आते हैं। – Landei
एक और समाधान
@tailrec
def collectUnique(l: List[Object], s: Set[Property], u: List[Object]): List[Object] = l match {
case Nil => u.reverse
case (h :: t) =>
if (s(h.property)) collectUnique(t, s, u) else collectUnique(t, s + h.prop, h :: u)
}
कार्यात्मक: डी! – noncom
मैं स्काला का कौन सा संस्करण उपयोग कर रहे हैं पता नहीं है, लेकिन निश्चित रूप से 2.8.2 है
list.distinct
संपादित करें (फिक्सिंग नीचे वोट)
list.distinctBy
मुझे इसे समूह के साथ काम करने का एक तरीका मिला, जिसमें एक के साथ termediary कदम:
def distinctBy[T, P, From[X] <: TraversableLike[X, From[X]]](collection: From[T])(property: T => P): From[T] = {
val uniqueValues: Set[T] = collection.groupBy(property).map(_._2.head)(breakOut)
collection.filter(uniqueValues)
}
इस तरह यह प्रयोग करें:
scala> distinctBy(List(redVolvo, bluePrius, redLeon))(_.color)
res0: List[Car] = List(redVolvo, bluePrius)
IttayD का पहला समाधान की तरह, लेकिन यह अद्वितीय मानों की सेट के आधार पर मूल संग्रह फिल्टर। groupBy
के लिए एक, map
के लिए एक और filter
के लिए एक: मेरी उम्मीदों सही हैं, तो यह तीन traversals करता है। यह मूल संग्रह के आदेश को बनाए रखता है, लेकिन यह आवश्यक नहीं है कि प्रत्येक संपत्ति के लिए पहला मूल्य लें। उदाहरण के लिए, यह इसके बजाय List(bluePrius, redLeon)
वापस कर सकता था।
, IttayD समाधान अभी भी तेजी के बाद से यह सिर्फ एक ही ट्रेवर्सल करता है।
मेरा समाधान भी नुकसान पहुंचाता है कि, यदि संग्रह में Car
एस वास्तव में समान हैं, तो दोनों आउटपुट सूची में होंगे। इसे filter
को हटाकर uniqueValues
को सीधे From[T]
के साथ वापस ले जाया जा सकता है। हालांकि, यह CanBuildFrom[Map[P, From[T]], T, From[T]]
की तरह लगता है मौजूद नहीं है ... सुझाव का स्वागत है!
:
def distinctBy[L, E](list: List[L])(f: L => E): List[L] =
list.foldLeft((Vector.empty[L], Set.empty[E])) {
case ((acc, set), item) =>
val key = f(item)
if (set.contains(key)) (acc, set)
else (acc :+ item, set + key)
}._1.toList
distinctBy(list)(_.property)
आप अधिक सामान्य समाधान के लिए सेक [एल] का उपयोग कर सकते हैं। –
- 1. सूची तत्वों के लगातार डुप्लीकेट हटाएं
- 2. ऑब्जेक्ट्स की सूची में ऑब्जेक्ट
- 3. स्कैला कॉपी ऑब्जेक्ट्स
- 4. संग्रह में डुप्लीकेट ढूंढना
- 5. डुप्लीकेट पंक्तियों को कैसे हटाएं और तालिका
- 6. कस्टम ऑब्जेक्ट्स की सूची छंटनी
- 7. पायथन - ऑब्जेक्ट्स की पठनीय सूची
- 8. स्कैला लिंक्ड सूची stackoverflow
- 9. डुप्लीकेट
- 10. ऑब्जेक्ट्स की सूची को कतार/कनवर्ट करने के लिए ऑब्जेक्ट्स की सूची
- 11. LINQ का उपयोग करके, ऑब्जेक्ट्स की दूसरी सूची के अंदर ऑब्जेक्ट्स की सूची का चयन करें
- 12. डुप्लीकेट
- 13. डुप्लीकेट
- 14. केवल डुप्लीकेट
- 15. डुप्लीकेट
- 16. सूची में एकाधिक ऑब्जेक्ट्स, सी #
- 17. स्कैला - सूचीओं की सूची एक सूची में बदलें: सूची [सूची [ए]] सूची [ए]
- 18. ऑब्जेक्ट्स की सूची के लिए JSON संरचना
- 19. ऑब्जेक्ट्स की एक सूची संग्रहीत करना
- 20. ऑब्जेक्ट्स की मनमाने ढंग से लंबी सूची
- 21. कॉफ़ेस्ट ऑब्जेक्ट्स की सूची से कॉलम निकालें
- 22. पायथन सॉर्टिंग - ऑब्जेक्ट्स की एक सूची
- 23. ऑब्जेक्ट्स की एक सूची प्रिंट करना
- 24. विभिन्न ऑब्जेक्ट्स की उदाहरण सूची बनाना
- 25. स्कैला "वैश्विक" कार्यों की एक सूची?
- 26. एसक्यूएल क्वेरी - 3 से अधिक डुप्लिकेट डुप्लीकेट हटाएं?
- 27. java.util.Iterator को स्कैला सूची में?
- 28. अनावश्यक प्रविष्टियों को हटाएं, स्कैला रास्ता
- 29. एप्लिकेशन सेटिंग्स में ऑब्जेक्ट्स की सूची कैसे स्टोर करें
- 30. जांचें कि ऑब्जेक्ट्स की सूची में एक निश्चित विशेषता मान
बजाय एक सेट का उपयोग कर एक सूची के बारे में क्या? इसके अलावा, आप ऑब्जेक्ट से क्यों व्यवहार कर रहे हैं, यानी कक्षा पदानुक्रम के शीर्ष पर? –