मेरे पास निम्न डेटा संरचना है:

persons: [
  { name: 'Joe',  age: 20 },
  { name: 'Alex', age: 24 },  
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
]

मैं प्रत्येक मौजूदा नाम के लिए सबसे पुराना व्यक्ति-वस्तु प्राप्त करना चाहता हूं। तो इस उदाहरण का परिणाम होगा:

filteredPersons: [
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
]

इसे कैसे प्राप्त किया जा सकता है? ध्यान दें कि विभिन्न नामों की संख्या निश्चित नहीं है।

2
leonheess 21 सितंबर 2020, 13:05

5 जवाब

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

आप Map और समान नामों के लिए वृद्धावस्था एकत्र करें।

इस आत्मा में एक फ़ंक्शन होता है जो दो वस्तुओं (या एक वस्तु और एक संभावित undefined) की तुलना करता है और यदि सत्य और b.age बड़ा है तो a.age, यह b देता है, अन्यथा a.

अंत में, परिणाम सेट के रूप में केवल मानचित्र के मान लिए जाते हैं।

const
    older = (a, b) => b?.age > a.age ? b : a,
    persons = [{ name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }],
    result = Array.from(persons.reduce((m, o) => m.set(
        o.name, 
        older(o, m.get(o.name))
    ), new Map).values());

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
3
3limin4t0r 21 सितंबर 2020, 14:50

एक ही पास में ऐसा करने के लिए, आप को नियोजित कर सकते हैं। Array.prototype.reduce() Map जिसमें एक कुंजी के रूप में name होगा और एक मूल्य-वस्तु के रूप में name के साथ अधिकतम age स्टोर करेगा।

एक बार Map तैयार हो जाने के बाद, आप Map.prototype.values():

const src = [{name:'Joe',age:20},{name:'Alex',age:24},{name:'Joe',age:34},{name:'Bob',age:19},{name:'Alex',age:56},],

    result = [...src
      .reduce((acc, {name, age}) => {
        const match = acc.get(name)
        match  ?
        match.age = Math.max(age, match.age) :
        acc.set(name, {name,age})
        return acc
      }, new Map)
      .values()
    ]
    
console.log(result)
.as-console-wrapper{min-height:100%;}
2
Yevgen Gorbunkov 21 सितंबर 2020, 13:17

बस reduce सरणी और सरणी में प्रत्येक व्यक्ति के लिए, जांचें कि क्या आइटम पहले सामने आया है, यदि ऐसा है तो सबसे पुराना रखें, अन्यथा केवल वर्तमान ऑब्जेक्ट रखें:

let results = persons.reduce((acc, person) => {                 // for each person in persons
  if(!acc[person.name] || acc[person.name].age < person.age) {  // if this person has never been encountered before (acc[person.name]) or if the already encountered one is younger (acc[person.name].age < person.age)
    acc[person.name] = person;                                  // store the current person under the name
  }
  return acc;
}, Object.create(null));                                        // Object.create(null) instead of {} to create a prototypeless object

यह इस प्रारूप { name: person, name: person, ... } में सबसे पुराने व्यक्तियों वाली एक वस्तु लौटाएगा। यदि आप उन्हें एक सरणी के रूप में प्राप्त करना चाहते हैं, तो Object.values को इस प्रकार कॉल करें:

let arrayResults = Object.values(results);

डेमो:

let persons = [{ name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }];

let results = persons.reduce((acc, person) => {
  if(!acc[person.name] || acc[person.name].age < person.age) {
    acc[person.name] = person;
  }
  return acc;
}, Object.create(null));

let arrayResults = Object.values(results);

console.log("results:", results);
console.log("arrayResults:", arrayResults);
1
ibrahim mahrir 21 सितंबर 2020, 13:25

आशा है कि यह आपके लिए अधिक समझ में आता है।

const persons = [
  { name: 'Joe',  age: 20 },
  { name: 'Alex', age: 24 },  
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
]

let personsObj = {}, mxPersons = []

persons.forEach(person => {
  if (personsObj[person.name] == undefined) {
    personsObj[person.name] = person.age
  } else {
    personsObj[person.name] = Math.max(person.age, personsObj[person.name])
  }
})
for (const [key, value] of Object.entries(personsObj)) {
  mxPersons.push({
    name: key,
    age: value
  })
}

console.log(mxPersons)
0
didv097 21 सितंबर 2020, 13:37

प्रति नाम सबसे पुराने लोगों को पहले सभी लोगों को उनके नाम के आधार पर समूहित करके प्राप्त किया जा सकता है, फिर प्रत्येक समूह के सबसे पुराने व्यक्ति को लें।

यह उत्तर दो सहायक कार्यों groupBy और maxBy का परिचय देता है, जो कुछ ओवरहेड जोड़ते हैं लेकिन सामान्य रूप से वास्तव में उपयोगी होते हैं।

const people = [
  { name: 'Joe',  age: 20 },
  { name: 'Alex', age: 24 },  
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
];

const oldestPeople = Array
  .from(groupBy(people, person => person.name).values())
  .map(people => maxBy(people, person => person.age));

console.log(oldestPeople);

function groupBy(iterable, fn) {
  const groups = new Map();
  for (const item of iterable) {
    const key = fn(item);
    if (!groups.has(key)) groups.set(key, []);
    groups.get(key).push(item);
  }
  return groups;
}

function maxBy(iterable, fn) {
  let max, maxValue;
  for (const item of iterable) {
    const itemValue = fn(item);
    if (itemValue <= maxValue) continue;
    [max, maxValue] = [item, itemValue];
  }
  return max;
}
0
3limin4t0r 21 सितंबर 2020, 14:08