2015-06-09 8 views
20

मुझे सरणी के माध्यम से पुनरावृत्ति के साथ कुछ मदद की ज़रूरत है, मैं पहिया रहना या पहिया को फिर से शुरू करना जारी रखता हूं।मैं कैसे जांच सकता हूं कि ऑब्जेक्ट्स की सरणी में डुप्लिकेट संपत्ति मान हैं या नहीं?

values = [ 
    { name: 'someName1' }, 
    { name: 'someName2' }, 
    { name: 'someName1' }, 
    { name: 'someName1' } 
] 

मैं कैसे जांच कर सकता है अगर वहाँ दो (या अधिक) एक ही नाम सरणी में मान रहे हैं? मुझे काउंटर की आवश्यकता नहीं है, अगर सरणी मान अद्वितीय नहीं हैं तो बस कुछ चर सेट करें। ध्यान रखें कि सरणी की लंबाई गतिशील है, सरणी मान भी है।

+0

@AmiTavory कम से कम एक स्पष्ट अंतर है - वह प्रश्न primitives ('arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7] की एक सरणी को देखता है;'), और यह वस्तुओं के गुणों के आधार पर deduping लग रहा है। अर्थपूर्ण, शायद, लेकिन दो सबसे ज्यादा वोट दिए गए उत्तरों इस मामले को बिल्कुल सही नहीं करते हैं। 'जितना अधिक आप जानते हैं' (मुझे एहसास है कि कुछ भी नहीं करेगा) – ruffin

+0

@ruffin प्वाइंट लिया गया। टिप्पणी हटा दी गई। –

उत्तर

37

उपयोग array.prototype.map और array.prototype.some:

var values = [ 
    { name: 'someName1' }, 
    { name: 'someName2' }, 
    { name: 'someName4' }, 
    { name: 'someName2' } 
]; 

var valueArr = values.map(function(item){ return item.name }); 
var isDuplicate = valueArr.some(function(item, idx){ 
    return valueArr.indexOf(item) != idx 
}); 
console.log(isDuplicate); 

JSFIDDLE.

+2

'इंडेक्सऑफ' बहुत खराब प्रदर्शन देगा, अगर सरणी बड़ी है। – thefourtheye

+5

मैं रिटर्न भाग को प्रतिस्थापित कर दूंगा: वापसी मूल्यअरे.इंडेक्सओएफ (आइटम, आईडीएक्स + 1)! == -1 –

+0

बहुत उपयोगी ... धन्यवाद –

22

ECMA स्क्रिप्ट 6 संस्करण

आप एक वातावरण है जो ECMA स्क्रिप्ट 6 के Set, तो आप Array.prototype.some उपयोग कर सकते हैं और एक Set वस्तु का समर्थन करता है में हैं, इस

let seen = new Set(); 
var hasDuplicates = values.some(function(currentObject) { 
    return seen.size === seen.add(currentObject.name).size; 
}); 

यहाँ की तरह, हम सम्मिलित करें Set में प्रत्येक ऑब्जेक्ट का name और हम यह जांचते हैं कि size जोड़ने से पहले और बाद में समान हैं। यह काम करता है क्योंकि Set.size अद्वितीय डेटा के आधार पर एक संख्या देता है (डेटा केवल अद्वितीय होने पर प्रविष्टियों को जोड़ता है)। यदि आपके पास डुप्लिकेट नाम हैं, तो आकार में वृद्धि नहीं होगी (क्योंकि डेटा अद्वितीय नहीं होगा) जिसका अर्थ है कि हम पहले से ही वर्तमान नाम देख चुके होंगे और यह सच हो जाएगा।


ECMA स्क्रिप्ट 5 संस्करण

आप Set का समर्थन नहीं है, तो आप एक सामान्य जावास्क्रिप्ट वस्तु ही है, इस

var seen = {}; 
var hasDuplicates = values.some(function(currentObject) { 

    if (seen.hasOwnProperty(currentObject.name)) { 
     // Current name is already seen 
     return true; 
    } 

    // Current name is being seen for the first time 
    return (seen[currentObject.name] = false); 
}); 

ही लिखा जा सकता है की तरह उपयोग कर सकते हैं संक्षेप में, इस

var seen = {}; 
var hasDuplicates = values.some(function (currentObject) { 
    return seen.hasOwnProperty(currentObject.name) 
     || (seen[currentObject.name] = false); 
}); 

नोट: दोनों मामलों में, हम Array.prototype.some का उपयोग करते हैं क्योंकि यह शॉर्ट-सर्किट होगा। जिस क्षण यह फ़ंक्शन से सच्चा मूल्य प्राप्त करता है, वह तुरंत true लौटाएगा, यह शेष तत्वों को संसाधित नहीं करेगा।

+0

'हैऑनप्रोपर्टी' का उपयोग करके दिलचस्प दृष्टिकोण। मैंने कुछ अन्य उत्तरों में देखा कि आपने टिप्पणी की है कि 'इंडेक्सऑफ' के बड़े सरणी में खराब प्रदर्शन होगा। क्या उपर्युक्त ES5 तरीका आपने बड़ी वस्तुओं के लिए सामान्य रूप से अधिक प्रदर्शन अनुकूल सुझाव दिया है? –

+0

@ जोशबीम 'इंडेक्सऑफ' को यह पता लगाने के लिए सरणी को फिर से चालू करना होगा कि क्या तत्व है या नहीं, लेकिन हैशिंग का उपयोग करने वाली कोई भी चीज़ बहुत तेज होगी। इसलिए, यदि सरणी काफी बड़ी है तो ES5 और ES6 दोनों तरीके बहुत तेज़ होंगे। – thefourtheye

+0

मैं कैसे सुनिश्चित कर सकता हूं, यह शेष तत्वों को संसाधित करेगा? –

0

आप map का उपयोग सिर्फ नाम वापस जाने के लिए कर सकते हैं, और उसके बाद जाँच करने के लिए इस forEach चाल का उपयोग करता है, तो यह कम से कम दो बार मौजूद है:

var areAnyDuplicates = false; 

values.map(function(obj) { 
    return obj.name; 
}).forEach(function (element, index, arr) { 
    if (arr.indexOf(element) !== index) { 
     areAnyDuplicates = true; 
    } 
}); 

Fiddle

+0

'इंडेक्सऑफ' बहुत खराब प्रदर्शन देगा, अगर सरणी बड़ी है। – thefourtheye

1

Underscore.js अंडरस्कोर के साथ कुछ तरीके किए जा सकते हैं। उनमें से एक यहां पर है। जांच कर रहा है कि सरणी पहले से ही अद्वितीय है या नहीं।

function isNameUnique(values){ 
    return _.uniq(values, function(v){ return v.name }).length == values.length 
} 

वेनिला जावास्क्रिप्ट साथ जाँच अगर वहाँ सरणी में कोई आवर्ती नाम है के द्वारा।

function isNameUnique(values){ 
    var names = values.map(function(v){ return v.name }); 
    return !names.some(function(v){ 
     return names.filter(function(w){ return w==v }).length>1 
    }); 
} 
2

एक सरल पाश का प्रयास करें: हम पहले और पिछले एक ही मूल्य की अनुक्रमणिका तुलना कर सकते हैं, तो सरल सरणी डुप्लिकेट है

var repeat = [], tmp, i = 0; 

while(i < values.length){ 
    repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp) 
} 

Demo

+0

यह सिर्फ उनके डी-डुप्लेड सरणी के साथ समाप्त होता है। – spartikus

0

पता करने के लिए :

समारोह:

var hasDupsSimple = function(array) { 

    return array.some(function(value) {       // .some will break as soon as duplicate found (no need to itterate over all array) 
     return array.indexOf(value) !== array.lastIndexOf(value); // comparing first and last indexes of the same value 
    }) 
} 

टेस्ट:

hasDupsSimple([1,2,3,4,2,7]) 
// => true 

hasDupsSimple([1,2,3,4,8,7]) 
// => false 

hasDupsSimple([1,"hello",3,"bye","hello",7]) 
// => true 

ऑब्जेक्ट की श्रृंखला हम पहले एक सरल सरणी के लिए वस्तुओं के मूल्यों में बदलने की आवश्यकता के लिए:

परिवर्तित map के साथ सरल सरणी में वस्तुओं की सरणी:

var hasDupsObjects = function(array) { 

    return array.map(function(value) { 
    return value.suit + value.rank 

    }).some(function(value, index, array) { 
     return array.indexOf(value) !== array.lastIndexOf(value); 
    }) 
} 

टेस्ट:

var cardHand = [ 
    { "suit":"spades", "rank":"ten" }, 
    { "suit":"diamonds", "rank":"ace" }, 
    { "suit":"hearts", "rank":"ten" }, 
    { "suit":"clubs", "rank":"two" }, 
    { "suit":"spades", "rank":"three" }, 
] 

hasDupsObjects(cardHand); 
// => false 

var cardHand2 = [ 
    { "suit":"spades", "rank":"ten" }, 
    { "suit":"diamonds", "rank":"ace" }, 
    { "suit":"hearts", "rank":"ten" }, 
    { "suit":"clubs", "rank":"two" }, 
    { "suit":"spades", "rank":"ten" }, 
] 

hasDupsObjects(cardHand2); 
// => true 
0

आप देख रहे हैं एक बूलियन के लिए उनका जल्द से जल्द किया जाएगा

var values = [ 
 
    { name: 'someName1' }, 
 
    { name: 'someName2' }, 
 
    { name: 'someName1' }, 
 
    { name: 'someName1' } 
 
] 
 

 
// solution 
 
var hasDuplicate = false; 
 
values.map(v => v.name).sort().sort((a, b) => { 
 
    if (a === b) hasDuplicate = true 
 
}) 
 
console.log('hasDuplicate', hasDuplicate)

संबंधित मुद्दे

 संबंधित मुद्दे