2012-08-05 78 views
5

Tôi muốn nhận được giá trị tối thiểu từ một mảng. Nếu dữ liệu chứa giá trị null, Math.min.apply trả lại 0 cho giá trị null. Vui lòng xem this JSFiddle example. Làm thế nào tôi có thể nhận được giá trị tối thiểu thực sự ngay cả khi giá trị null tồn tại trong mảng?Math.min.apply trả về 0 cho null

Mã (giống như trong JSFiddle ví dụ):

var arrayObject= [ {"x": 1, "y": 5}, {"x": 2, "y": 2}, {"x": 3, "y": 9}, {"x": 4, "y": null}, {"x": 5, "y": 12} ]; 

var max = Math.max.apply(Math, arrayObject.map(function(o){return o.y;})); 
var min = Math.min.apply(Math, arrayObject.map(function(o){return o.y;})); 

$("#max").text(max); 
$("#min").text(min); 
+2

Không có JSON trong ví dụ của bạn ... được sửa. –

+0

Chức năng 'Math.min' thực hiện (hàm bên trong)' ToNumber() 'trên mỗi phần tử mảng, do đó coerces các giá trị thành * Số *. Coercion hút, chúng tôi biết điều đó. ': P' –

+1

@ ŠimeVidas chỉ đơn giản là rời khỏi thuộc tính sẽ làm cho nó 'undefined', mà lần lượt chuyển sang' NaN' mà dễ dàng lọc ra với '.filter (isFinite)' – Esailija

Trả lời

9

Vâng, giá trị bằng số cho null0. Nếu bạn không muốn null giá trị được được xem xét, bạn phải lọc chúng ra:

var values = arrayObject.map(function(o){ 
    return o.y; 
}).filter(function(val) { 
    return val !== null 
}); 

Reference: Array#filter

+2

Hoặc ánh xạ 'null' thành' Infinity'. Sẽ lưu một số byte và các cuộc gọi hàm 'n' bổ sung. – Prinzhorn

+0

@Prinzhorn: Vâng, điều đó cũng sẽ hoạt động ... chỉ cần bạn phải ánh xạ lại chúng cho 'max' to' -Infinity'. Phụ thuộc vào những gì bạn sẽ làm với dữ liệu. –

+0

Giống như vậy: http://stackoverflow.com/a/11817906/139010 –

0
var validArray = $.grep(arrayObject, function(item, _){ 
        return item.y != null; 
       }); 
//That gives a new array without null values for "y" 

Bây giờ làm ..

var min = Math.min.apply(Math, validArray.map(function(o){return o.y;})); 
+0

Mã OP đã làm – Dancrumb

6

Thay thế cho giải pháp của Felix: xử lý null+ hoặc - inf tính tương đối cho các cuộc gọi tối thiểu và tối đa, tương ứng.

var max = Math.max.apply(Math, arrayObject.map(function(o) { 
    return o.y == null ? -Infinity : o.y; 
})); 
var min = Math.min.apply(Math, arrayObject.map(function(o) { 
    return o.y == null ? Infinity : o.y; 
})); 
+0

Lời thề. Tôi chưa bao giờ thấy vô tận được đưa vào sử dụng. Tôi sẽ upvote này hai lần nếu tôi có thể. :) –

+1

Có lý do nào để sử dụng hằng số trên 'Số', không phải chữ' Infinity' (và '-Infinity') có thể dễ dàng hơn không? – Bergi

+0

@Bergi điểm tốt, cảm ơn. Đã chỉnh sửa. –

4

Tôi nghĩ thay vì tính lập bản đồ, lọc ra null giá trị, và áp dụng Math.min/max (theo đề nghị của các câu trả lời khác) các reduce function sẽ giúp bạn tiết kiệm thời gian và mã số, bằng cách trực tiếp áp dụng logic:

var arrayObject= [ {"x": 1, "y": 5}, {"x": 2, "y": 2}, {"x": 3, "y": 9}, {"x": 4, "y": null}, {"x": 5, "y": 12} ]; 
var min = var arrayObject.reduce(function(m, o) { 
    return (o.y != null && o.y < m) ? o.y : m; 
}, Infinity); 
var max = var arrayObject.reduce(function(m, o) { 
    return (o.y != null && o.y > m) ? o.y : m; 
}, -Infinity); 
+0

Giải pháp thú vị. Hiệu suất đạt được về ký hiệu O là gì? –

+0

'O (n)' không giống với bất kỳ giải pháp nào khác. – Esailija

+0

Ký hiệu Landau? Không ai. Nhưng bạn lưu một số cuộc gọi chức năng và một số bộ nhớ bằng cách không tạo các mảng trung gian – Bergi