मेरे पास निम्न स्रोत सरणी है:

const list = [
    {
        students: [ 'peter', 'bob', 'john']
    },
    {
        students: [ 'thomas', 'sarah', 'john']
    },
    {
        students: [ 'john', 'sarah', 'jack']
    }
];

और मैं अद्वितीय छात्र नाम और उनकी गिनती प्राप्त करना चाहता हूं, अंतिम परिणाम इस तरह होना चाहिए:

{
    'john': 3,
    'sarah': 2,
    'thomas': 1,
    'jack': 1,
    'peter': 1,
    'bob': 1
}

यहाँ मेरा प्रयास है:

const unique = list.reduce(function(total, curr){
  const students = curr.students;
  for (c of students) {
    if (!total[c]) {
      total[c] = 1
    } else {
      total[c] += 1;
    }
  }
  return total;

}, {});

इसे करने का कोई बेहतर तरीका है? या तेज और साफ तरीका? धन्यवाद

0
teebeetee 25 सितंबर 2019, 02:55

2 जवाब

सबसे बढ़िया उत्तर

मैं पहले सरणियों को समतल करूंगा, फिर reduce के साथ गिनूंगा:

const list = [
    {
        students: [ 'peter', 'bob', 'john']
    },
    {
        students: [ 'thomas', 'sarah', 'john']
    },
    {
        students: [ 'john', 'sarah', 'jack']
    }
];


const allStudents = list.flatMap(({ students }) => students);
const count = allStudents.reduce((a, name) => {
  a[name] = (a[name] || 0) + 1;
  return a;
}, {});
console.log(count);

यदि आप चाहते हैं कि गुणों को भी क्रमित किया जाए, तो वस्तु का Object.entries लें, इसे क्रमबद्ध करें, फिर इसे Object.fromEntries के साथ एक वस्तु में बदल दें:

const list = [
    {
        students: [ 'peter', 'bob', 'john']
    },
    {
        students: [ 'thomas', 'sarah', 'john']
    },
    {
        students: [ 'john', 'sarah', 'jack']
    }
];


const allStudents = list.flatMap(({ students }) => students);
const count = allStudents.reduce((a, name) => {
  a[name] = (a[name] || 0) + 1;
  return a;
}, {});
const sorted = Object.fromEntries(
  Object.entries(count).sort((a, b) => b[1] - a[1])
);
console.log(sorted);

यदि आपका वातावरण फ़्लैटमैप, या एंट्रीज़ का समर्थन नहीं करता है, तो एक पॉलीफ़िल का उपयोग करें, या एक अलग विधि के साथ फ़्लैटन/ग्रुप का उपयोग करें:

const list = [
    {
        students: [ 'peter', 'bob', 'john']
    },
    {
        students: [ 'thomas', 'sarah', 'john']
    },
    {
        students: [ 'john', 'sarah', 'jack']
    }
];


const allStudents = [].concat(...list.map(({ students }) => students));
const count = allStudents.reduce((a, name) => {
  a[name] = (a[name] || 0) + 1;
  return a;
}, {});
const sortedEntries = Object.entries(count).sort((a, b) => b[1] - a[1]);
const sortedObj = sortedEntries.reduce((a, [prop, val]) => {
  a[prop] = val;
  return a;
}, {});
console.log(sortedObj);

ध्यान रखें कि ऑब्जेक्ट प्रॉपर्टी ऑर्डर केवल ES6+ वातावरण में निर्दिष्ट है। जबकि Object.fromEntries किसी ऑब्जेक्ट को प्रविष्टियों के समान क्रम में बनाने के लिए विनिर्देशन की गारंटी नहीं है, यह वैसे भी करता है, सौभाग्य से मैंने कभी भी किसी भी कार्यान्वयन का सामना किया है। (यदि आप अभी भी इसके बारे में चिंतित हैं, तो आप पुराने ढंग का उपयोग कर सकते हैं reduce इसके बजाय ऑब्जेक्ट बनाने की विधि, जैसे तीसरे स्निपेट में)

2
CertainPerformance 25 सितंबर 2019, 03:08

कार्यात्मक प्रोग्रामिंग का उपयोग करने का प्रयास करें: मानचित्र का संयोजन और 2 विधियों को कम करें।

const listMapped = list.map(it=> it.students)

const listReduced = listMapped.reduce((acc, rec) => {
return [...acc.concat(rec)]
}, [])

const listCounted = listReduced.reduce((acc, rec) => {
acc[rec]
? acc[rec] += 1
: acc[rec] = 1
return acc 
}, {})

console.log(listCounted)
0
sinnerwithguts 25 सितंबर 2019, 16:41