Мога ли да накарам underscore.js да върне масив при намиране на само един елемент?


1

Здравейте. Правя си разни експерименти с underscore.js и домашните, и ми изникна следния въпрос.

Имам кода:

  1. _.chain(people)
  2.     .filter(function (person) {
  3.         return person.averageMark >= 70 && person.averageMark <= 80;
  4.     })
  5.     .each(function (person) {
  6.         console.log(person.toString());
  7.     });

който си работи идеално - връща колекция от обекти, на които мога да им дам .toString и ще си изплюе това, което ми трябва. При следната операция обаче, нещата са по различни:

 

  1. _.chain(people)
  2.         .max(function (person) {
  3.             return person.averageMark.toString();
  4.         })
  5.         .each(function(person){
  6.             console.log(person.toString());
  7.         });

.max ми връща обекта с най-голям averageMark, а не масив. И когато му дам toString(), той ми итерира по пропъртитата (fname, lname, averageMark) и ми ги принтира тях. Как мога да направя така, че дори и underscore да ми върне един обект, той да е в масив?




Отговори



1

Противоречат си функциите ти.
Така както си написал chain-a, по-скоро ползвай .sortBy, вместо .max, защото .max връща един елемент и .each след него ще итерира по пропъртитата. Имай предвид, че след сортиране може да викаш .reverse(), ако искаш обратния ред.

Ако пък целта ти е да принтнеш само търсения човек, сложи само .value(), вместо .each.

Ако пък държиш да е в масив, вместо .each, с .map му кажи да го конвертира в масив и накрая пак .value().


от valentin_lozev (1012 точки)


0
Ясно, ето какво пропускам значи - не бях пробвал директно value на .max

от kris4o1993 (3555 точки)

0
_.chain(people) .map(function(person){ return [person]; }) .max(function (person) { return person[0].averageMark; }) .value();
Така го взимаш и в масив, но едва ли има смисъл.

от valentin_lozev (1012 точки)


1

.max по природа е функция, която има за цел да намери и върне точно един елемент. Ако искаш да ти върне нещо различно е много вероятно да я изполваш грешно.

Все пак ако искаш да го направиш в JavaScript винаги има начин :)

Използвай нещо от сорта на това:

  1. var oldMax = _.prototype.max
  2.  
  3. _.prototype.max = function(){
  4.     var max = oldMax.apply(this, arguments);
  5.     max._wrapped = new Array(max._wrapped);
  6.     return max;
  7. };

Може да има и по-лесен начин (да са оставили начин за екстендване или нещо подобно), но за момента се сещам за това ;)


от westi3m (5621 точки)


1

Ами да ти кажа поиграх си, че ми стана любопитно, обаче се получиха само някакви мизерии. Направи си го чисто, по стандартния начин: 

   var result = _.max(people, function (person) {
            return person.age;
        });
   arr.push(result);
 
 То хубаво, че може да се прави chaining, ама не е пък нужно мисля цялата програма да ти в един chain.

от ADimanova (548 точки)