Xử lý dữ liệu javascript
arr1.push({phong: "phong1", "dsnv": "1,2,3,4,5", "sl": "10"});
arr1.push({phong: "phong2", "dsnv": "1,4,5", "sl": "5"});
arr1.push({phong: "phong3", "dsnv": "1,2,3", "sl": "15"});
arr1.push({phong: "phong4", "dsnv": "1,6,5", "sl": "20"});
Chào anh chị em, số là e có dữ liệu thô như bên dưới, em cần tìm những số trong dsnv trùng nhau giữa các phòng, nếu phòng cùng có mã nhân viên thì phòng có số lượng lớn hơn giảm đi 1, vậy có cách nào ngắn gọn hơn không ạ, theo cách em làm thì rất dài và nhiều vòng lặp nên thấy hơi tù ạ. mong anh chị em giúp đỡ
1 CÂU TRẢ LỜI
Bạn thử xem xử lý như dưới đây có được không
Cũng phải mất 2 vòng lặp lồng nhau (^^;)
// Khởi tạo dữ liệu để test
let rooms = [];
rooms.push({id: "phong1", "staffs": "1,2,3,4,5", "capacity": "6"});
rooms.push({id: "phong2", "staffs": "1,2,4", "capacity": "6"});
rooms.push({id: "phong3", "staffs": "1,2,3", "capacity": "6"});
rooms.push({id: "phong4", "staffs": "2,3,4", "capacity": "5"});
rooms.push({id: "phong5", "staffs": "3,4", "capacity": "4"});
// Xử lý qua mảng các phòng họp.
// Chuyển list nhân viên từ string sang array, và thêm vào trường để lưu số lượng thực tế
let staffs = [];
for (let room of rooms) {
room.staffsArray = room.staffs.split(',');
// Tạo biến staffs để lưu danh sách mã số nhân viên, không bị trùng lặp
staffs = staffs.concat(room.staffsArray.filter((item) => item && staffs.indexOf(item) < 0));
room.realCapacity = parseInt(room.capacity);
}
// Lặp qua từng nhân viên một
// Với mỗi nhân viên thì lặp qua từng phòng, phòng nào có nhân viên đó thì trừ đi một
// Đồng thời lưu lại thông tin xem phòng nào có số lượng ít nhất
// Sau đó, tăng lại một cho phòng có số lượng ít nhất này
for (let staff of staffs) {
let minRoomIndex;
let minNum;
for (index in rooms) {
let room = rooms[index];
if (room.staffsArray.includes(staff)) {
if (minRoomIndex === undefined || room.realCapacity < minNum) {
minNum = room.realCapacity;
minRoomIndex = index;
}
room.realCapacity--;
}
}
rooms[minRoomIndex].realCapacity += 1;
}
Mình tính ra thì với dữ liệu ở trên sẽ ra kết quả
phòng 1: 3
phòng 2: 4
phòng 3: 4
phòng 4: 3
phòng 5: 2
Có vẻ trùng với kết quả mong muốn của bạn ở phần comment rồi Không rõ có đúng là đề bài yêu cầu thế không nhỉ
Vậy mình trừ hết rồi dựa theo số lượng mà + thì hay hơn bạn nhỉ? nếu làm theo này sẽ có trường hợp như sau
Bảng gốc
Phòng 1 - 1,2 - 2
Phòng 2 - 1,2,3 - 3
Phòng 3 - 2,3 - 2
Step 1
Phòng 1 - 1,2 - 2 <
Phòng 2 - 2,3 - 2 \\ Bị trừ
Phòng 3 - 2,3 - 2
Step 2
Phòng 1 - 1,2 - 2 <
Phòng 2 - 3 - 1 \\ Bị trừ
Phòng 3 - 3 - 1 \\ Bị trừ
Step 3
Phòng 1 - 1,2 - 2
Phòng 2 - 3 - 1 <
Phòng 3 - null - 0 \\ Bị trừ
nhưng thực tế để phân bố đều tránh phòng bị ùn tắc thì sẽ có dạng
Phòng 1: 1
Phòng 2: 1
Phòng 3: 1
hoặc do mình xử lý từ sql đã sai rồi :-<
@zingler Căn bản là mục đích cuối cùng bạn muốn làm gì, và đang cố gắng giải quyết vấn đề như thế nào thôi
Nếu mục đích là để phân bố nhân viên vào trong từng phòng, thì có vẻ ngay logic ban đầu bạn đưa ra ở câu hỏi đã có vẻ không ổn rồi
Cho mình hỏi rõ hơn, cái trường số lượng "sl"
ở đây là số lượng gì vậy bạn nhỉ? Số lượng nhân viên (đếm từ trong mảng danh sách mã số nhân viên), hay sức chứa còn lại của phòng
@thangtd90 à đúng rồi, từ đầu cái đề đã sai rồi, thật ra nó là số lượng nhân viên = length của dsnv rồi , thế k nghĩ ra lưu dsnv như bạn nhỉ, dựa theo cách của bạn mình thấy ổn rồi
@zingler Uhm, nếu là số lượng nhân viên thì có thể đếm trực tiếp từ cái mảng nhân viên ra rồi, nên không cần phải lưu nó lại làm gì. Lúc đó đoạn code khai báo ban đầu có thể sửa lại một cách gọn hơn là
let rooms = [];
rooms.push({id: "phong1", "staffs": "1,2,3,4,5"});
rooms.push({id: "phong2", "staffs": "1,2,4"});
rooms.push({id: "phong3", "staffs": "1,2,3"});
rooms.push({id: "phong4", "staffs": "2,3,4"});
rooms.push({id: "phong5", "staffs": "3,4"});
let staffs = [];
for (let room of rooms) {
room.staffsArray = room.staffs.split(',');
// Tính trực tiếp số lượng từ độ dài của mảng
room.staffCounts = room.staffsArray.length;
staffs = staffs.concat(room.staffsArray.filter((item) => item && staffs.indexOf(item) < 0));
}
thôi
Tuy nhiên đoạn code kia sau khi chạy thì sẽ ra kết quả
Phòng 1: 1 (chứa người có mã nhân viên là 5)
Phòng 2: 1 (1)
Phòng 3: 2 (2, 3)
Phòng 4: 1 (4)
Phòng 5: 0
Trong khi nếu sắp xếp chuẩn thì mỗi phòng có thể chứa 1 người là
Phòng 1: 1 (5)
Phòng 2: 1 (1)
Phòng 3: 1 (2)
Phòng 4: 1 (3)
Phòng 5: 1 (4)
Tức miêu tả về thuật toán bạn đưa ra ở đề bài, đó là giữ lại mã số nhân viên ở phòng có số lượng nhỏ nhất, và trừ số lượng ở các phòng khác đi 1, thì chưa phải là thuật toán tối ưu nhất rồi (^^;)
@thangtd90 bởi vậy mình mới lên tham khảo anh chị em đó haha, với cách làm của bạn hiện tại mình thấy ok r, cảm ơn bạn nhiều nha
@thangtd90 với bài toán này bạn có nghĩ ra được hướng giải nào tối ưu nhất cho bài toán không ạ? từ khâu sql luôn ấy ạ
Bạn có thể viết nhanh một ví dụ đầu ra mong muốn được không. Và cái phần
"dsnv": "1,2,3,4,5"
tại sao không lưu cái 1,2,3,4,5 ở dạng mảng nhỉ.à mình lưu dữ liệu trong sql dạng string, muốn dạng mảng cũng được mà bác. Ví dụ ở trên thì 4 phòng đều có nv 1, mà phòng 2 số lượng ít nhất nên các phòng khác số lượng -1 hết.
@zingler
Yêu cầu của bạn vẫn còn nhiều điểm mập mờ quá nhỉ, bạn miêu tả chi tiết hơn được không
Ví dụ như trường hợp mình có dữ liệu thế này, thì bạn kỳ vọng output sẽ trả ra như thế nào nhỉ
@thangtd90
Output đại khái sẽ vậy, như với mã nhân viên 1 thì phòng 1,2,3 đều có, nên khi so thì sẽ chọn cái có số lượng nhỏ nhất, nếu bằng nhau thì giữ phòng đang đi so, ở ví dụ này thì phòng 2 và 3 sẽ bị trừ.
@zingler Tức là nếu 2 hoặc 3 phòng có số lượng bằng nhau và cùng là số lượng nhỏ nhất, thì sẽ trừ ở tất cả các phòng bạn nhỉ
Cụ thể thì với dữ liệu ở trên thì sẽ qua các bước xử lý
Kết quả có vẻ ra khác với kết quả của bạn ở trên
@thangtd90 ở step 2 số lượng phòng 2 đã nhỏ hơn phòng 1 rồi bác, đề bài là tìm ra nhân viên ở cùng nằm 2 phòng, thì ưu tiên phòng số lượng nhỏ nhất, tránh số liệu ảo, ví dụ tuy ông này được phân công làm ở 2 phòng, nhưng thời điểm hiện tại ông ấy ngồi ở 1 phòng thôi, phòng còn lại có ghế trống thì dựa vào code để hiển thị số lượng dư ghế cho người khác ấy bác
@zingler
Step 2 là step so sánh đến nhân viên có mã số là 2 bạn nhỉ. Lúc đó thì làm sao phòng 1 lại có số lượng nhỏ hơn phòng 2 được nhỉ
Cả 3 phòng 1, 2, 3 đều khởi đầu với số lượng là 6. Và như ở phía trên thì bạn có ghi là
thì tức là sau Step 1, thì phòng 2 và 3 sẽ còn lại 5, và phòng 1 sẽ là 6, chứ nhỉ
@thangtd90
Đề bài là vậy bác ạ
@zingler à mình hiểu rồi, cám ơn bạn nhé Ở trên mình hiểu nhầm một chút, phải là giữ nguyên số lượng ở phòng có số lượng ít nhất, và trừ 1 ở tất cả các phòng còn lại, chứ không phải là trừ 1 ở các phòng có số lượng ít nhất