ฉันเชื่อว่าฉันได้เรียนรู้แนวคิดพื้นฐานบางส่วน / มากที่สุด / ส่วนใหญ่ที่เกี่ยวกับการเขียนโปรแกรมการทำงานใน JavaScript อย่างไรก็ตามฉันมีปัญหาในการอ่านรหัสฟังก์ชั่นโดยเฉพาะแม้แต่รหัสที่ฉันเขียนและสงสัยว่าใครสามารถให้คำแนะนำเคล็ดลับแนวปฏิบัติที่ดีที่สุดคำศัพท์และอื่น ๆ ที่สามารถช่วยฉันได้
ใช้รหัสด้านล่าง ฉันเขียนรหัสนี้ โดยมีจุดมุ่งหมายที่จะกำหนดความคล้ายคลึงกันร้อยละระหว่างวัตถุสองระหว่างการพูดและ{a:1, b:2, c:3, d:3}
{a:1, b:1, e:2, f:2, g:3, h:5}
ผมผลิตรหัสในการตอบสนองต่อคำถามนี้ในกองมากเกิน เพราะฉันไม่แน่ใจเหมือนกันว่าเปอร์เซ็นต์ที่คล้ายคลึงกันที่โปสเตอร์ถามเกี่ยวกับอะไรฉันจึงให้สี่ชนิดที่แตกต่างกัน:
- เปอร์เซ็นต์ของกุญแจในวัตถุที่ 1 ที่สามารถพบได้ในที่ 2
- ร้อยละของค่าในวัตถุที่ 1 ที่สามารถพบได้ใน 2 รวมถึงการทำซ้ำ
- เปอร์เซ็นต์ของค่าในวัตถุที่ 1 ที่สามารถพบได้ในที่ 2 โดยไม่อนุญาตให้ทำซ้ำและ
- เปอร์เซ็นต์ของคู่ {key: value} ในวัตถุที่ 1 ที่สามารถพบได้ในวัตถุที่สอง
ฉันเริ่มด้วยรหัสที่จำเป็นพอสมควร แต่รู้ได้อย่างรวดเร็วว่านี่เป็นปัญหาที่เหมาะสมสำหรับการเขียนโปรแกรมการทำงาน โดยเฉพาะอย่างยิ่งฉันรู้ว่าถ้าฉันสามารถแยกฟังก์ชั่นหรือสามสำหรับแต่ละสี่กลยุทธ์ข้างต้นที่กำหนดประเภทของคุณสมบัติที่ฉันกำลังมองหาเพื่อเปรียบเทียบ (เช่นคีย์หรือค่า ฯลฯ ) จากนั้นฉันอาจ สามารถลด (ให้อภัยการเล่นคำ) ส่วนที่เหลือของรหัสเป็นหน่วยที่ทำซ้ำได้ คุณรู้ว่าทำให้มันแห้ง ดังนั้นฉันจึงเปลี่ยนเป็นการเขียนโปรแกรมใช้งานได้ ฉันค่อนข้างภูมิใจกับผลลัพธ์ที่ได้ฉันคิดว่ามันสมเหตุสมผลดีและฉันคิดว่าฉันเข้าใจสิ่งที่ฉันทำได้ค่อนข้างดี
อย่างไรก็ตามแม้จะมีการเขียนรหัสด้วยตัวเองและเข้าใจทุกส่วนของมันในระหว่างการก่อสร้างเมื่อตอนนี้ฉันมองย้อนกลับไปฉันก็ยังงุนงงมากกว่าทั้งนิดหน่อยเกี่ยวกับวิธีอ่านครึ่งบรรทัดใด ๆ โดยเฉพาะรวมทั้งวิธีการ "grok" สิ่งใดที่โค้ดครึ่งหนึ่งกำลังทำอยู่ ฉันพบว่าตัวเองกำลังทำลูกศรทางจิตเพื่อเชื่อมต่อส่วนต่าง ๆ ที่ย่อยสลายไปอย่างรวดเร็วของปาเก็ตตี้
ดังนั้นทุกคนสามารถบอกฉันได้ว่า "อ่าน" บางส่วนของรหัสที่ซับซ้อนมากขึ้นในทางที่กระชับและมีส่วนช่วยให้ฉันเข้าใจว่าฉันกำลังอ่านอะไรอยู่? ฉันเดาว่าชิ้นส่วนที่ทำให้ฉันได้มากที่สุดคือชิ้นส่วนที่มีลูกศรอ้วนหลายอันติดกันและ / หรือชิ้นส่วนที่มีวงเล็บหลายอันติดกัน อีกครั้งที่แกนกลางของพวกเขาในที่สุดฉันก็สามารถหาเหตุผลได้ แต่ (ฉันหวังว่า) มีวิธีที่ดีกว่าในการดำเนินการอย่างรวดเร็วและชัดเจนและตรงไปตรงมา "รับ" การเขียนโปรแกรมจาวาสคริปต์ที่ใช้งานได้
อย่าลังเลที่จะใช้รหัสบรรทัดใด ๆ จากด้านล่างหรือแม้แต่ตัวอย่างอื่น ๆ อย่างไรก็ตามหากคุณต้องการคำแนะนำเบื้องต้นจากฉันนี่คือบางส่วน เริ่มด้วยสิ่งที่เรียบง่ายอย่างมีเหตุผล obj => key => obj[key]
จากใกล้ถึงจุดสิ้นสุดของรหัสที่มีนี้ที่ถูกส่งผ่านเป็นพารามิเตอร์ไปยังฟังก์ชัน: คนเราอ่านและเข้าใจได้อย่างไร const getXs = (obj, getX) => Object.keys(obj).map(key => getX(obj)(key));
ตัวอย่างอีกต่อไปเป็นหนึ่งในฟังก์ชั่นเต็มรูปแบบจากที่อยู่ใกล้กับจุดเริ่มต้น: map
ส่วนสุดท้ายทำให้ฉันโดยเฉพาะอย่างยิ่ง
โปรดทราบว่า ณ เวลานี้ฉันไม่ได้มองหาการอ้างอิงถึง Haskell หรือสัญกรณ์นามธรรมสัญลักษณ์หรือพื้นฐานของการแก้เผ็ด ฯลฯสิ่งที่ฉันกำลังมองหาคือประโยคภาษาอังกฤษที่ฉันสามารถพูดอย่างเงียบ ๆ ในขณะที่มองหาบรรทัดของรหัส หากคุณมีการอ้างอิงที่เจาะจงเป็นพิเศษนั้นยอดเยี่ยม แต่ฉันก็ไม่ได้มองหาคำตอบที่บอกว่าฉันควรไปอ่านตำราพื้นฐาน ฉันทำไปแล้วและฉันก็ได้รับตรรกะอย่างน้อยก็อย่างน้อย โปรดทราบว่าฉันไม่ต้องการคำตอบที่ละเอียดถี่ถ้วน (แม้ว่าจะยินดีต้อนรับความพยายามดังกล่าว): แม้คำตอบสั้น ๆ ที่ให้วิธีการที่ยอดเยี่ยมในการอ่านบรรทัดหนึ่งบรรทัดของรหัสที่มีปัญหาอย่างอื่นจะได้รับการชื่นชม
ฉันคิดว่าส่วนหนึ่งของคำถามนี้คือ: ฉันสามารถอ่านรหัสการทำงานเชิงเส้นได้คุณรู้ซ้ายไปขวาและบนลงล่างหรือไม่ หรือถูกบังคับให้สร้างภาพทางจิตของการเดินสายสปาเก็ตตี้ในหน้าของโค้ดที่ไม่เชิงเส้นอย่างแน่นอน และถ้าเราต้องทำอย่างนั้นเรายังคงต้องอ่านรหัสดังนั้นเราจะนำข้อความเชิงเส้นและต่อสายสปาเก็ตตี้ได้อย่างไร
เคล็ดลับใด ๆ ที่จะได้รับการชื่นชม
const obj1 = { a:1, b:2, c:3, d:3 };
const obj2 = { a:1, b:1, e:2, f:2, g:3, h:5 };
// x or X is key or value or key/value pair
const getXs = (obj, getX) =>
Object.keys(obj).map(key => getX(obj)(key));
const getPctSameXs = (getX, filter = vals => vals) =>
(objA, objB) =>
filter(getXs(objB, getX))
.reduce(
(numSame, x) =>
getXs(objA, getX).indexOf(x) > -1 ? numSame + 1 : numSame,
0
) / Object.keys(objA).length * 100;
const pctSameKeys = getPctSameXs(obj => key => key);
const pctSameValsDups = getPctSameXs(obj => key => obj[key]);
const pctSameValsNoDups = getPctSameXs(obj => key => obj[key], vals => [...new Set(vals)]);
const pctSameProps = getPctSameXs(obj => key => JSON.stringify( {[key]: obj[key]} ));
console.log('obj1:', JSON.stringify(obj1));
console.log('obj2:', JSON.stringify(obj2));
console.log('% same keys: ', pctSameKeys (obj1, obj2));
console.log('% same values, incl duplicates:', pctSameValsDups (obj1, obj2));
console.log('% same values, no duplicates: ', pctSameValsNoDups(obj1, obj2));
console.log('% same properties (k/v pairs): ', pctSameProps (obj1, obj2));
// output:
// obj1: {"a":1,"b":2,"c":3,"d":3}
// obj2: {"a":1,"b":1,"e":2,"f":2,"g":3,"h":5}
// % same keys: 50
// % same values, incl duplicates: 125
// % same values, no duplicates: 75
// % same properties (k/v pairs): 25