JavaScript对象数组按属性的最小值进行过滤

时间:2018-11-01 08:47:54

标签: javascript arrays math ecmascript-6

我需要通过“ rest”属性的最小值过滤此对象数组。这是一种方法。还有其他方法吗?

'data'变量是链接函数的结果。还有其他方法可以在Math.min()函数中再次调用“数据”变量而无需这样做。

let data = 
[ { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } ]

let result = data.filter(e=> e.rest === Math.min(...data.map(f=>f.rest) ) );
console.log(result);

// result is
//[ { size: 5, qty: 2, rest: 0 },
//  { size: 2, qty: 5, rest: 0 },
//  { size: 1, qty: 10, rest: 0 }]

4 个答案:

答案 0 :(得分:2)

data.map内的

data.filterO(N^2);对于O(N)解决方案,请提前遍历data以计算最小值,然后以该最小值计算filter

let data = 
[ { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } ];
const minRest = Math.min(...data.map(({ rest }) => rest));

let result = data.filter(({ rest }) => rest === minRest);
console.log(result);

答案 1 :(得分:1)

最简单的方法是将min函数从过滤器中拉出,如下所示:

let min = Math.min(...data.map(item => item.rest))

这效率更高,因为我们不再遍历数据以查找过滤器每次迭代的最小值。

我们现在有n * 2遍,而不是n ^ 2遍。 (n是数据集的大小,在这种情况下为5)

下面的完整示例:

   let data = [ 
     { size: 5, qty: 2, rest: 0 },
     { size: 2, qty: 5, rest: 0 },
     { size: 1, qty: 10, rest: 0 },
     { size: 3, qty: 3, rest: 1 },
     { size: 4, qty: 2, rest: 2 } 
   ]

  let min = Math.min(...data.map(item => item.rest))
  let result = data.filter(item => item.rest === min)
  console.log(result)

希望这会有所帮助!

劳埃德

答案 2 :(得分:0)

听起来您想对列表进行排序。我将按照以下步骤进行操作:

const result = data.sort((a, b) => a.rest - b.rest)

答案 3 :(得分:0)

imo。最简单/最好的解决方案是@CertainPerformance给您的解决方案。

只是想添加另一个具有线性运行时的解决方案(实际上仅在数组上迭代一次)

%h3
  =conmodels_t('cons.models', 'my_events')
%table#some_table.my_table
  %tr.header
    %th{rowspan: 2} View
    %th{rowspan: 2} Date and Time
    %th{colspan: 3} Place
    %th{rowspan: 2} How Long
    - if display_some_field?(@pres.application, :event, :some_exp) && course_event_general_expenses?(course)
      %th Expense
      %th How Intense
    %th{rowspan: 2}  State
    %th.actions{rowspan: 2}  Action
  %tr.header
    %th SubHeader 1
    %th SubHeader 2
    %th SubHeader 3
  - if course.events.count > 0
    - events.each do |event|
      - rowspan = event.event_locations.size+1
      - tr do
        %td{rowspan: rowspan}= link_to event.event_name
        %td{rowspan: rowspan}
          = show_date event.event_date
          = "#{event.event_start} - #{event.event_end}"
        %td{rowspan: rowspan}
          = "#{event.duration}"
          - if event.workshop_duration
            = " (#{event.workshop_duration})"
        - if display_something
          %th{rowspan: rowspan}= event.is_other_location ? number_to_currency(event.general_expenses) : ''
          %th{rowspan: rowspan}= event.is_other_location ? number_to_percentage(event_general_expenses(event), precision: 0) : ''
        %th{rowspan: rowspan}= course_status_name(event.status)
        %td{rowspan: rowspan}
          - if event.can_edit?
            .button=link_to 'Edit', edit_event_path(@course.app, event)
          - elsif event.course.ended?
            .button=link_to 'View', some_app_path(@course.path, event)
      - event.event_locations.drop(1).each do |location|
        %tr.row1
          %td= location.Under1Subheader
          %td= location.Under2ndSubheader
          %td= location.Under3rdSubheader
  - else
    %tr
      %td Nothing to view

@ mathieux51让我有了另一个想法,知道如何在方法链中执行此操作,但是其可读性/清晰度/意图不如其他方法好:

let data = [
  { size: 5, qty: 2, rest: 0 },
  { size: 2, qty: 5, rest: 0 },
  { size: 1, qty: 10, rest: 0 },
  { size: 3, qty: 3, rest: 1 },
  { size: 4, qty: 2, rest: 2 } 
];

let result = data.reduce((result, item) => {
  let minRest = result.length? result[0].rest: item.rest;

  if (item.rest < minRest) {
    minRest = item.rest;
    result.length = 0;
  }

  if (item.rest === minRest) {
    result.push(item);
  }

  return result;
}, []);

console.log(result);