मैं यह निर्धारित करने के एक सुंदर तरीके की तलाश कर रहा हूं कि जावास्क्रिप्ट सरणी में किस तत्व की उच्चतम घटना ( मोड ) है।
उदाहरण के लिए, में
['pear', 'apple', 'orange', 'apple']
'apple'
तत्व सबसे लगातार एक है।
मैं यह निर्धारित करने के एक सुंदर तरीके की तलाश कर रहा हूं कि जावास्क्रिप्ट सरणी में किस तत्व की उच्चतम घटना ( मोड ) है।
उदाहरण के लिए, में
['pear', 'apple', 'orange', 'apple']
'apple'
तत्व सबसे लगातार एक है।
जवाबों:
यह सिर्फ विधा है। यहां एक त्वरित, गैर-अनुकूलित समाधान है। यह O (n) होना चाहिए।
function mode(array)
{
if(array.length == 0)
return null;
var modeMap = {};
var maxEl = array[0], maxCount = 1;
for(var i = 0; i < array.length; i++)
{
var el = array[i];
if(modeMap[el] == null)
modeMap[el] = 1;
else
modeMap[el]++;
if(modeMap[el] > maxCount)
{
maxEl = el;
maxCount = modeMap[el];
}
}
return maxEl;
}
2009 के बाद से जावास्क्रिप्ट में कुछ विकास हुए हैं - मुझे लगा कि मैं एक और विकल्प जोड़ूंगा। मैं दक्षता से कम चिंतित हूँ जब तक यह वास्तव में "सुरुचिपूर्ण" कोड की मेरी परिभाषा है (जैसा कि ओपी द्वारा निर्धारित) पठनीयता का पक्षधर है - जो निश्चित रूप से व्यक्तिपरक है ...
function mode(arr){
return arr.sort((a,b) =>
arr.filter(v => v===a).length
- arr.filter(v => v===b).length
).pop();
}
mode(['pear', 'apple', 'orange', 'apple']); // apple
इस विशेष उदाहरण में, सेट के दो या दो से अधिक तत्वों में समान घटनाएँ होनी चाहिए, फिर जो सरणी में नवीनतम दिखाई देगा उसे वापस कर दिया जाएगा। यह भी इंगित करने योग्य है कि यह आपके मूल सरणी को संशोधित करेगा - जिसे अगर आप Array.slice
पहले से कॉल के साथ चाहें तो रोका जा सकता है ।
संपादित करें: कुछ के साथ उदाहरण को अद्यतन किया ES6 वसा वाले तीरों के क्योंकि 2015 हुआ और मुझे लगता है कि वे बहुत सुंदर लग रहे हैं ... यदि आप पीछे की संगतता के साथ संबंध रखते हैं तो आप इसे संशोधन इतिहास में पा सकते हैं ।
George Jempty's
संबंधों के लिए एल्गोरिथम खाता रखने के अनुरोध के अनुसार , मैं Matthew Flaschen's
एल्गोरिथ्म के एक संशोधित संस्करण का प्रस्ताव करता हूं ।
function modeString(array) {
if (array.length == 0) return null;
var modeMap = {},
maxEl = array[0],
maxCount = 1;
for (var i = 0; i < array.length; i++) {
var el = array[i];
if (modeMap[el] == null) modeMap[el] = 1;
else modeMap[el]++;
if (modeMap[el] > maxCount) {
maxEl = el;
maxCount = modeMap[el];
} else if (modeMap[el] == maxCount) {
maxEl += "&" + el;
maxCount = modeMap[el];
}
}
return maxEl;
}
यह अब एक &
प्रतीक द्वारा सीमांकित मोड तत्व (ओं) के साथ एक स्ट्रिंग लौटाएगा । जब परिणाम प्राप्त होता है तो उस पर विभाजित किया जा सकता है&
तत्व और आपके पास आपका मोड है।
एक अन्य विकल्प मोड तत्व (एस) की एक सरणी लौटना होगा जैसे:
function modeArray(array) {
if (array.length == 0) return null;
var modeMap = {},
maxCount = 1,
modes = [];
for (var i = 0; i < array.length; i++) {
var el = array[i];
if (modeMap[el] == null) modeMap[el] = 1;
else modeMap[el]++;
if (modeMap[el] > maxCount) {
modes = [el];
maxCount = modeMap[el];
} else if (modeMap[el] == maxCount) {
modes.push(el);
maxCount = modeMap[el];
}
}
return modes;
}
उपरोक्त उदाहरण में आप तब मोड के एक सरणी के रूप में फ़ंक्शन के परिणाम को संभालने में सक्षम होंगे।
modes
करने की आवश्यकता नहीं है [array[0]]
। यह सुनिश्चित करेगा कि आपके पास डुप्लिकेट हैं modes
। यह चालvar modes = []
==
करने के ===
लिए उदाहरण बदलने की सलाह देते हैं
Emissary के ES6 + उत्तर के आधार पर , आप Array.prototype.reduce
अपनी तुलना करने के लिए उपयोग कर सकते हैं (जैसा कि आपके सरणी को छांटने, पॉप करने और संभावित रूप से म्यूट करने के विपरीत), जो मुझे लगता है कि काफी चालाक है।
const mode = (myArray) =>
myArray.reduce(
(a,b,i,arr)=>
(arr.filter(v=>v===a).length>=arr.filter(v=>v===b).length?a:b),
null)
मैं अशक्त करने के लिए डिफ़ॉल्ट कर रहा हूँ, जो हमेशा आपको एक सच्ची प्रतिक्रिया नहीं देगा यदि अशक्त एक संभावित विकल्प है जिसके लिए आप फ़िल्टर कर रहे हैं, हो सकता है कि यह एक वैकल्पिक दूसरा तर्क हो सकता है
नकारात्मक पक्ष, अन्य विभिन्न समाधानों के साथ, यह है कि यह 'ड्रा स्टेट्स' को संभालता नहीं है, लेकिन यह अभी भी थोड़ा अधिक शामिल फ़ंक्शन के साथ प्राप्त किया जा सकता है।
a=['pear', 'apple', 'orange', 'apple'];
b={};
max='', maxi=0;
for(let k of a) {
if(b[k]) b[k]++; else b[k]=1;
if(maxi < b[k]) { max=k; maxi=b[k] }
}
जैसा कि मैं साक्षात्कारकर्ताओं के लिए एक प्रश्नोत्तरी के रूप में इस फ़ंक्शन का उपयोग कर रहा हूं, मैं अपना समाधान पोस्ट करता हूं:
const highest = arr => (arr || []).reduce( ( acc, el ) => {
acc.k[el] = acc.k[el] ? acc.k[el] + 1 : 1
acc.max = acc.max ? acc.max < acc.k[el] ? el : acc.max : el
return acc
}, { k:{} }).max
const test = [0,1,2,3,4,2,3,1,0,3,2,2,2,3,3,2]
console.log(highest(test))
यहां एक घोषणात्मक दृष्टिकोण की कोशिश कर रहा है। यह समाधान प्रत्येक शब्द की घटनाओं को जोड़ने के लिए एक वस्तु बनाता है। फिर ऑब्जेक्ट में पाए जाने वाले उच्चतम मान के लिए प्रत्येक शब्द की कुल घटनाओं की तुलना करके ऑब्जेक्ट को एक सरणी में फ़िल्टर करता है।
const arr = ['hello', 'world', 'hello', 'again'];
const tally = (acc, x) => {
if (! acc[x]) {
acc[x] = 1;
return acc;
}
acc[x] += 1;
return acc;
};
const totals = arr.reduce(tally, {});
const keys = Object.keys(totals);
const values = keys.map(x => totals[x]);
const results = keys.filter(x => totals[x] === Math.max(...values));
एक और समाधान के लिए समय:
function getMaxOccurrence(arr) {
var o = {}, maxCount = 0, maxValue, m;
for (var i=0, iLen=arr.length; i<iLen; i++) {
m = arr[i];
if (!o.hasOwnProperty(m)) {
o[m] = 0;
}
++o[m];
if (o[m] > maxCount) {
maxCount = o[m];
maxValue = m;
}
}
return maxValue;
}
अगर संक्षिप्तता मायने रखती है (यह नहीं है), तो:
function getMaxOccurrence(a) {
var o = {}, mC = 0, mV, m;
for (var i=0, iL=a.length; i<iL; i++) {
m = a[i];
o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
if (o[m] > mC) mC = o[m], mV = m;
}
return mV;
}
यदि गैर-मौजूद सदस्यों से बचा जाना है (जैसे विरल सरणी), तो एक अतिरिक्त hasOwnProperty परीक्षण की आवश्यकता होती है:
function getMaxOccurrence(a) {
var o = {}, mC = 0, mV, m;
for (var i=0, iL=a.length; i<iL; i++) {
if (a.hasOwnProperty(i)) {
m = a[i];
o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
if (o[m] > mC) mC = o[m], mV = m;
}
}
return mV;
}
getMaxOccurrence([,,,,,1,1]); // 1
यहां अन्य उत्तर अपरिभाषित लौट आएंगे ।
एक और जेएस समाधान: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php
यह भी कोशिश कर सकते हैं:
let arr =['pear', 'apple', 'orange', 'apple'];
function findMostFrequent(arr) {
let mf = 1;
let m = 0;
let item;
for (let i = 0; i < arr.length; i++) {
for (let j = i; j < arr.length; j++) {
if (arr[i] == arr[j]) {
m++;
if (m > mf) {
mf = m;
item = arr[i];
}
}
}
m = 0;
}
return item;
}
findMostFrequent(arr); // apple
यहाँ O (n) जटिलता के साथ करने का एक और ES6 तरीका है
const result = Object.entries(
['pear', 'apple', 'orange', 'apple'].reduce((previous, current) => {
if (previous[current] === undefined) previous[current] = 1;
else previous[current]++;
return previous;
}, {})).reduce((previous, current) => (current[1] >= previous[1] ? current : previous))[0];
console.log("Max value : " + result);
function mode(arr){
return arr.reduce(function(counts,key){
var curCount = (counts[key+''] || 0) + 1;
counts[key+''] = curCount;
if (curCount > counts.max) { counts.max = curCount; counts.mode = key; }
return counts;
}, {max:0, mode: null}).mode
}
यहां इस समस्या का समाधान है, लेकिन संख्याओं के साथ और नए 'सेट' फीचर का उपयोग करना। यह बहुत अच्छा नहीं है, लेकिन मुझे निश्चित रूप से यह लिखने में बहुत मज़ा आया और यह कई अधिकतम मूल्यों का समर्थन करता है।
const mode = (arr) => [...new Set(arr)]
.map((value) => [value, arr.filter((v) => v === value).length])
.sort((a,b) => a[1]-b[1])
.reverse()
.filter((value, i, a) => a.indexOf(value) === i)
.filter((v, i, a) => v[1] === a[0][1])
.map((v) => v[0])
mode([1,2,3,3]) // [3]
mode([1,1,1,1,2,2,2,2,3,3,3]) // [1,2]
वैसे उत्पादन के लिए इसका उपयोग न करें यह केवल ईएस 6 और एरे कार्यों के साथ इसे हल करने का एक उदाहरण है।
यहाँ मेरा समाधान है: -
function frequent(number){
var count = 0;
var sortedNumber = number.sort();
var start = number[0], item;
for(var i = 0 ; i < sortedNumber.length; i++){
if(start === sortedNumber[i] || sortedNumber[i] === sortedNumber[i+1]){
item = sortedNumber[i]
}
}
return item
}
console.log( frequent(['pear', 'apple', 'orange', 'apple']))
पढ़ने के लिए वास्तव में आसान के लिए, मैं इसे बनाए रखने योग्य कोड:
function getMaxOcurrences(arr = []) {
let item = arr[0];
let ocurrencesMap = {};
for (let i in arr) {
const current = arr[i];
if (ocurrencesMap[current]) ocurrencesMap[current]++;
else ocurrencesMap[current] = 1;
if (ocurrencesMap[item] < ocurrencesMap[current]) item = current;
}
return {
item: item,
ocurrences: ocurrencesMap[item]
};
}
आशा है कि यह किसी की मदद करता है;)
यह समाधान एक टाई के मामले में एक सरणी के कई तत्वों को वापस कर सकता है। उदाहरण के लिए, एक सरणी
arr = [ 3, 4, 3, 6, 4, ];
दो मोड मान हैं: 3
और 6
।
यहाँ समाधान है।
function find_mode(arr) {
var max = 0;
var maxarr = [];
var counter = [];
var maxarr = [];
arr.forEach(function(){
counter.push(0);
});
for(var i = 0;i<arr.length;i++){
for(var j=0;j<arr.length;j++){
if(arr[i]==arr[j])counter[i]++;
}
}
max=this.arrayMax(counter);
for(var i = 0;i<arr.length;i++){
if(counter[i]==max)maxarr.push(arr[i]);
}
var unique = maxarr.filter( this.onlyUnique );
return unique;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
};
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;
नोट: ct सरणी की लंबाई है।
function getMode()
{
for (var i = 0; i < ct; i++)
{
value = num[i];
if (i != ct)
{
while (value == num[i + 1])
{
c = c + 1;
i = i + 1;
}
}
if (c > greatest)
{
greatest = c;
mode = value;
}
c = 0;
}
}
const mode = (str) => {
return str
.split(' ')
.reduce((data, key) => {
let counter = data.map[key] + 1 || 1
data.map[key] = counter
if (counter > data.counter) {
data.counter = counter
data.mode = key
}
return data
}, {
counter: 0,
mode: null,
map: {}
})
.mode
}
console.log(mode('the t-rex is the greatest of them all'))
इसे भी आजमाएं, यह ब्राउज़र संस्करण में नहीं है।
function mode(arr){
var a = [],b = 0,occurrence;
for(var i = 0; i < arr.length;i++){
if(a[arr[i]] != undefined){
a[arr[i]]++;
}else{
a[arr[i]] = 1;
}
}
for(var key in a){
if(a[key] > b){
b = a[key];
occurrence = key;
}
}
return occurrence;
}
alert(mode(['segunda','terça','terca','segunda','terça','segunda']));
कृपया ध्यान दें कि यह फ़ंक्शन सरणी में नवीनतम घटना लौटाता है जब 2 या अधिक प्रविष्टियां समान संख्या में दिखाई देती हैं!
यहां निर्मित संस्करणों का उपयोग करके आधुनिक संस्करण दिया गया है (इसलिए यह उन चीजों से अधिक काम करता है जिन्हें अद्वितीय तारों में परिवर्तित किया जा सकता है):
'use strict';
const histogram = iterable => {
const result = new Map();
for (const x of iterable) {
result.set(x, (result.get(x) || 0) + 1);
}
return result;
};
const mostCommon = iterable => {
let maxCount = 0;
let maxKey;
for (const [key, count] of histogram(iterable)) {
if (count > maxCount) {
maxCount = count;
maxKey = key;
}
}
return maxKey;
};
console.log(mostCommon(['pear', 'apple', 'orange', 'apple']));
मुझे लगता है कि आपके पास दो दृष्टिकोण हैं। जिसके दोनों फायदे हैं।
इसके बाद सॉर्ट करें या गिनें और आप के लिए काउंटिंग करने के लिए हैश टेबल का उपयोग करें।
हैशटेबल अच्छा है क्योंकि एक बार जब आप प्रसंस्करण कर लेते हैं तो आपके पास सभी विशिष्ट तत्व भी होते हैं। यदि आपके पास लाखों आइटम थे, हालांकि, डुप्लिकेट दर कम होने पर हैश टेबल बहुत मेमोरी का उपयोग कर सकता है। इसके बाद सॉर्ट, काउंट एप्रोच में बहुत अधिक चलाया हुआ मेमोरी फुटप्रिंट होगा।
var array = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17],
c = {}, // counters
s = []; // sortable array
for (var i=0; i<array.length; i++) {
c[array[i]] = c[array[i]] || 0; // initialize
c[array[i]]++;
} // count occurrences
for (var key in c) {
s.push([key, c[key]])
} // build sortable array from counters
s.sort(function(a, b) {return b[1]-a[1];});
var firstMode = s[0][0];
console.log(firstMode);
आप यह कोशिश कर सकते हैं:
// using splice()
// get the element with the highest occurence in an array
function mc(a) {
var us = [], l;
// find all the unique elements in the array
a.forEach(function (v) {
if (us.indexOf(v) === -1) {
us.push(v);
}
});
l = us.length;
while (true) {
for (var i = 0; i < l; i ++) {
if (a.indexOf(us[i]) === -1) {
continue;
} else if (a.indexOf(us[i]) != -1 && a.length > 1) {
// just delete it once at a time
a.splice(a.indexOf(us[i]), 1);
} else {
// default to last one
return a[0];
}
}
}
}
// using string.match method
function su(a) {
var s = a.join(),
uelms = [],
r = {},
l,
i,
m;
a.forEach(function (v) {
if (uelms.indexOf(v) === -1) {
uelms.push(v);
}
});
l = uelms.length;
// use match to calculate occurance times
for (i = 0; i < l; i ++) {
r[uelms[i]] = s.match(new RegExp(uelms[i], 'g')).length;
}
m = uelms[0];
for (var p in r) {
if (r[p] > r[m]) {
m = p;
} else {
continue;
}
}
return m;
}
आप इसे O (n) जटिलता में हल कर सकते हैं
var arr = [1,3,54,56,6,6,1,6];
var obj = {};
/* first convert the array in to object with unique elements and number of times each element is repeated */
for(var i = 0; i < arr.length; i++)
{
var x = arr[i];
if(!obj[x])
obj[x] = 1;
else
obj[x]++;
}
console.log(obj);//just for reference
/* now traverse the object to get the element */
var index = 0;
var max = 0;
for(var obIndex in obj)
{
if(obj[obIndex] > max)
{
max = obj[obIndex];
index = obIndex;
}
}
console.log(index+" got maximum time repeated, with "+ max +" times" );
उपरोक्त कोड को चलाने के लिए बस क्रोम कंसोल में कॉपी और पेस्ट करें।
यह फ़ंक्शन हर प्रकार की जानकारी के लिए सामान्य कार्य है। यह तत्वों की घटना को गिनता है और फिर अधिकतम होने वाले तत्वों के साथ सरणी देता है।
function mode () {
var arr = [].slice.call(arguments);
if ((args.length == 1) && (typeof args[0] === "object")) {
args = args[0].mode();
}
var obj = {};
for(var i = 0; i < arr.length; i++) {
if(obj[arr[i]] === undefined) obj[arr[i]] = 1;
else obj[arr[i]]++;
}
var max = 0;
for (w in obj) {
if (obj[w] > max) max = obj[w];
}
ret_val = [];
for (w in obj) {
if (obj[w] == max) ret_val.push(w);
}
return ret_val;
}
function mode(){
var input = $("input").val().split(",");
var mode = [];
var m = [];
var p = [];
for(var x = 0;x< input.length;x++){
if(m.indexOf(input[x])==-1){
m[m.length]=input[x];
}}
for(var x = 0; x< m.length;x++){
p[x]=0;
for(var y = 0; y<input.length;y++){
if(input[y]==m[x]){
p[x]++;
}}}
for(var x = 0;x< p.length;x++){
if(p[x] ==(Math.max.apply(null, p))){
mode.push(m[x]);
}}
$("#output").text(mode);}
यहाँ मेरा रास्ता है। मैं डेटा मुट्ठी में समूह की कोशिश करता हूं।
const _ = require("underscore")
var test = [ 1, 1, 2, 1 ];
var groupResult = _.groupBy(test, (e)=> e);
GroupResult होना चाहिए
{
1: [1, 1, 1]
2: [2]
}
फिर उस संपत्ति को ढूंढें जिसमें सबसे लंबी सरणी है
function findMax(groupResult){
var maxArr = []
var max;
for(var item in groupResult){
if(!max) {
max = { value:item, count: groupResult[item].length } ;
maxArr.push(max);
continue;
}
if(max.count < groupResult[item].length){
maxArr = [];
max = { value:item, count: groupResult[item].length }
maxArr.push(max)
} else if(max === groupResult[item].length)
maxArr.push({ value:item, count: groupResult[item].length })
}
return maxArr;
}
पूरा कोड जैसा दिखता है
const _ = require("underscore")
var test = [ 1, 1, 2, 1 ];
var groupResult= _.groupBy(test, (e)=> e);
console.log(findMax(groupResult)[0].value);
function findMax(groupResult){
var maxArr = []
var max;
for(var item in groupResult){
if(!max) {
max = { value:item, count: groupResult[item].length } ;
maxArr.push(max);
continue;
}
if(max.count < groupResult[item].length){
maxArr = [];
max = { value:item, count: groupResult[item].length }
maxArr.push(max)
} else if(max === groupResult[item].length)
maxArr.push({ value:item, count: groupResult[item].length })
}
return maxArr;
}
var cats = ['Tom','Fluffy','Tom','Bella','Chloe','Tom','Chloe'];
var counts = {};
var compare = 0;
var mostFrequent;
(function(array){
for(var i = 0, len = array.length; i < len; i++){
var word = array[i];
if(counts[word] === undefined){
counts[word] = 1;
}else{
counts[word] = counts[word] + 1;
}
if(counts[word] > compare){
compare = counts[word];
mostFrequent = cats[i];
}
}
return mostFrequent;
})(cats);
ES6 के साथ, आप इस तरह विधि की श्रृंखला बना सकते हैं:
function findMostFrequent(arr) {
return arr
.reduce((acc, cur, ind, arr) => {
if (arr.indexOf(cur) === ind) {
return [...acc, [cur, 1]];
} else {
acc[acc.indexOf(acc.find(e => e[0] === cur))] = [
cur,
acc[acc.indexOf(acc.find(e => e[0] === cur))][1] + 1
];
return acc;
}
}, [])
.sort((a, b) => b[1] - a[1])
.filter((cur, ind, arr) => cur[1] === arr[0][1])
.map(cur => cur[0]);
}
console.log(findMostFrequent(['pear', 'apple', 'orange', 'apple']));
console.log(findMostFrequent(['pear', 'apple', 'orange', 'apple', 'pear']));
यदि दो तत्वों की घटना समान है, तो यह दोनों को वापस कर देगा। और यह किसी भी प्रकार के तत्व के साथ काम करता है।
arr
दायरे के अंदर नहीं करना चाहिए जहाँ उस चर को पहले से ही एक पैरामीटर के रूप में परिभाषित किया गया है। यह उन बगों को जन्म दे सकता है जिनके आधार पर ब्राउज़र का उपयोग किया जाता है।
arr
द्वारा संदर्भित है arr.indexOf(cur)
? शीर्ष पैरामीटर, या कम के अंदर एक ??