Tổng số javascript Codewars tích cực

Đơn giản, đó là vì hàm Array.prototype.sort trong javascript sửa đổi nội dung thực tế của cùng một thể hiện của mảng cũng như trả về tham chiếu cho cùng một mảng, Nói cách khác, nó không trả về một mảng mới với nội dung đã sửa đổi, nó sửa đổi . Đó là lý do tại sao nó không hoạt động khi bạn xóa dòng

const m = numbers.sort( (a, b) => a - b )[2];

Nhưng, tại sao nó không hoạt động khi bạn cố đặt logic tương tự với dòng mã tiếp theo?

const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);

Sự cố xảy ra khi giá trị nhỏ nhất của mảng nằm ở chỉ số lớn hơn 2 chẳng hạn

[ 15, 28, 4, 2, 43 ]

khi chúng ta cố gắng thực thi mã trên mảng này, hãy thực hiện từng bước một để biết sai ở đâu

function sumTwoSmallestNumbers(numbers) {  
    const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
    const b = a.reduce( (acc, n) => acc + n);
    return b
};
const arr = [ 15, 28, 4, 2, 43 ]
const result = sumTwoSmallestNumbers(arr)
console.log(result)

Khi thực thi mã trước đó, điều đầu tiên mà hàm sẽ thực hiện là lọc. Nó sẽ lặp qua các phần tử của mảng

  • Bắt đầu từ chỉ số 0 => arr[0] = 15

    Kiểm tra điều kiện. 15 < numbers.sort( (a, b) => a - b )[2] => (15 < 15) => sai

Để ý. như tôi đã giải thích trước đó, rằng hàm sắp xếp sẽ thay đổi mảng thực thay vì tạo một mảng mới, điều đó có nghĩa là khi thử kiểm tra điều kiện lần đầu tiên, mảng sẽ được sắp xếp, có nghĩa là nếu nó chưa được sắp xếp,

Trước khi tiếp tục lặp lại filter, hãy làm rõ rằng thứ tự mới của mảng sau khi sắp xếp đã được thực hiện khi cố gắng kiểm tra điều kiện như sau

[ 2, 4, 15, 28, 43 ]
  • Chỉ mục 1 => mảng[1] = 4

    Kiểm tra điều kiện. 4 < numbers.sort( (a, b) => a - b )[2] => (4 < 15) => đúng

  • Chỉ mục 2 => mảng[2] = 15

    Kiểm tra điều kiện. 15 < numbers.sort( (a, b) => a - b )[2] => (15 < 15) => sai

  • Các yếu tố còn lại

Phần kết luận

Như bạn có thể nhận thấy, giá trị

const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
1 đã được kiểm tra hai lần và giá trị
const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
2, hoàn toàn không được kiểm tra, đó là do sự thay đổi đột ngột về thứ tự của mảng trong quá trình lặp lại hiện đang diễn ra của phương thức filter. Điều này đã dẫn đến việc đặt giá trị của
const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
2 vào một vị trí đã được kiểm tra và giá trị của
const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
1 vào một vị trí chưa được kiểm tra

Lưu ý Đây không phải là một giải pháp tối ưu cho một vấn đề như vậy, nó thực hiện quá nhiều công việc để có được giải pháp, (lọc, sắp xếp, rút ​​gọn), đây là những thao tác tốn kém để thực hiện. Một giải pháp tốt hơn sẽ giống như thế này, bao gồm một vòng lặp duy nhất thông qua các phần tử của mảng

const a = numbers.filter(v => v < numbers.sort( (a, b) => a - b )[2]);
6

Là thành viên beta của CodeWars, tôi vừa hoàn thành khóa đào tạo bài kata “Tổng dương”. Hãy bắt đầu tham gia cùng tôi và bắt đầu đào tạo

Nếu bạn đã là thành viên, hãy nhấp vào đây để đào tạo về “Tổng tích cực”

Một dãy số được truyền vào một hàm. Sự trở lại là tổng của tất cả các số dương. Nếu không có gì để thêm, tổng mặc định được đặt thành 0 ( 0 ). Ví dụ [1, -4, 7, 12] => 1 + 7 + 12 = 20

Chia vấn đề thành các bước nhỏ, dễ quản lý. Tại sao? . Làm từng bước nhỏ, trước khi bạn biết điều đó, nhiệm vụ lớn đã hoàn thành

  1. Đặt giá trị ban đầu của tổng thành không (0)
  2. Thu thập phần tử đầu tiên trong mảng
    • nếu giá trị lớn hơn 0
      • thêm giá trị vào tổng
      • chuyển sang phần tử tiếp theo
    • nếu giá trị nhỏ hơn 0
      • chuyển sang phần tử tiếp theo
  3. Lặp lại bước 2 cho đến khi tất cả các yếu tố đã được đánh giá

Cắt bỏ sự lộn xộn. Xác định những gì thực sự cần thiết để giải quyết vấn đề

  • Nhập số
  • Đầu ra của tổng

Các nhà phát triển yêu thích mã DRY. DRY có nghĩa là Đừng lặp lại chính mình. Có bước nào đang được lặp lại không?

  • Xác định xem một giá trị là dương hay âm
  • Cộng các số nguyên dương vào tổng

SET  VARIABLE sum TO default 0   
LOOP input array 
  IF array element IS > 0 
    ADD array element value TO sum value 
END LOOP 
RETURN sum value 

function positiveSum(arr) {
  for(var i = 0 , sum = 0 ; i < arr.length ; i++){
    if( arr[i] > 0 ){
      sum = sum + arr[i]
    }
  }    
  return sum;
}

TẤT CẢ CÁC BÀI KIỂM TRA ĐÃ THÔNG QUA. CÓ

Vì vậy, bất cứ khi nào tôi hoàn thành một thử thách, tôi đều xem qua các giải pháp của người khác để tìm bất cứ điều gì tôi có thể cải thiện. Lần này, tôi biết được có 2 hàm hoàn thành công việc, hàm JavaScript filter() & reduce(). Giải pháp của tôi có thể được viết lại hoàn toàn KHÔNG CÓ vòng lặp. Tôi thừa nhận, tôi thích phiên bản tái cấu trúc hơn, mặc dù cả hai đều tuyệt vời và hoàn thành công việc

Giải pháp tái cấu trúc

function positiveSum (arr) {
  return arr.filter(x => x > 0).reduce((a, b) => a + b, 0);
}

lọc()

Bộ lọc JavaScript() trả về một mảng chứa tất cả các phần tử mảng vượt qua bài kiểm tra được đưa ra dưới dạng một hàm. Một số điều quan trọng cần lưu ý về filter()

  • nó sẽ không thực thi trên một mảng trống
  • nó không thay đổi mảng ban đầu

Vì vậy, bước này là nơi tất cả các số nguyên âm bị loại bỏ và một mảng chỉ các số nguyên dương (nếu có) được trả về

Để biết thêm thông tin về hàm JavaScript filter(), hãy xem tại đây trên W3Schools

giảm bớt()

Hàm JavaScript reduce() giảm một mảng thành một giá trị. Nó đi qua từng phần tử của mảng được đính kèm từ trái sang phải và thực thi hàm được cung cấp trên mỗi. Nó trả về một bộ tích lũy chỉ ưa thích cho một kết quả hoặc tổng số. Một điều quan trọng cần lưu ý về reduce()

  • nó không thực thi trên một mảng trống

Đây là nơi các phần tử dương trong mảng được trả về bởi hàm filter() được cộng lại với nhau