JavaScript'te fonksiyonel programlamanın altında yatan temel kavramların bazılarını / çoğunu / çoğunu öğrendiğime inanıyorum. Ancak, özellikle fonksiyonel kod, hatta yazdığım kod okumakta sorun var ve herkes bana yardımcı olabilecek herhangi bir işaretçi, ipuçları, en iyi uygulamalar, terminoloji, vb verebilir olup olmadığını merak ediyorum.
Aşağıdaki kodu alın. Bu kodu yazdım. İki nesne arasında, say {a:1, b:2, c:3, d:3}
ve arasında benzerlik yüzdesi atamayı amaçlamaktadır {a:1, b:1, e:2, f:2, g:3, h:5}
. Stack Overflow bu soruya yanıt olarak kod üretti . Posterin ne tür bir yüzde benzerlik taşıdığını tam olarak bilmiyordum, dört farklı tür sağladım:
- 2. nesnede bulunan 1. nesnedeki anahtarların yüzdesi,
- kopyalar da dahil olmak üzere 2. nesnede bulunabilen 1. nesnedeki değerlerin yüzdesi,
- 2. nesnede bulunan ve kopyaya izin verilmeyen değerlerin yüzdesi ve
- 2. nesnede bulunan 1. nesnedeki {key: value} çiftlerinin yüzdesi.
Makul bir zorunluluk koduyla başladım, ancak bunun işlevsel programlama için çok uygun bir sorun olduğunu çabucak fark ettim. Özellikle, karşılaştırmak istediğim özellik türünü tanımlayan yukarıdaki dört stratejinin her biri için bir işlev veya üç ayıklayabilseydim (örneğin, anahtarlar veya değerler vb.) Kodun geri kalanını tekrarlanabilir birimlere indirgeyebilir (kelimelerdeki oyunu affedebilir). BUNU KURU halde tut. Böylece fonksiyonel programlamaya geçtim. Sonuçtan oldukça gurur duyuyorum, bence oldukça zarif ve bence ne yaptığımı gayet iyi anladım.
Ancak, kodu kendim yazmış ve inşaat sırasında her parçasını anlamış olsam bile, şimdi tekrar baktığımda, hem belirli bir yarım satırın nasıl okunacağı hem de nasıl yapılacağı konusunda biraz şaşkın olmaya devam ediyorum. "grok" kod herhangi bir yarım satır aslında ne yapıyor. Kendimi hızlı bir şekilde spagetti karmaşasına dönüşen farklı parçaları bağlamak için zihinsel oklar yaparken buluyorum.
Peki, birisi bana daha kıvrımlı kod parçalarının bazılarını hem kısa hem de okuduğum şeyi anlamama katkıda bulunan bir şekilde nasıl "okuyacağımı" söyleyebilir mi? Beni en çok etkileyen parçalar üst üste birkaç yağ oku olan ve / veya üst üste birkaç parantez içeren bölümler. Yine, özlerinde, sonunda mantığı anlayabilirim, ancak (umarım) hızlı ve net bir şekilde ve doğrudan bir işlevsel JavaScript programlama hattını "almak" için daha iyi bir yol vardır.
Aşağıdan herhangi bir kod satırını ve hatta diğer örnekleri kullanmaktan çekinmeyin. Ancak, benden bazı ilk öneriler almak istiyorsanız, işte birkaç tane. Oldukça basit biriyle başlayın. Kodun sonuna yakın itibaren, bir işleve parametre olarak geçirilir, bu var: obj => key => obj[key]
. Bunu nasıl okuyup anlıyoruz? Daha uzun bir örneği başından yakınlarından bir tam fonksiyon geçerli: const getXs = (obj, getX) => Object.keys(obj).map(key => getX(obj)(key));
. Son map
kısım özellikle beni alıyor.
Not zamanla bu noktada ben değilim Lütfen değil vs. Haskell yapılan atıflar veya sembolik soyut gösterimde veya-işlemden temelleri, arayan ne am seyir için ben sessizce ağız kod satırı bakarak kullanımın oldukça İngilizce cümleler olduğunu. Özellikle tam olarak buna değinen referanslarınız varsa, harika, ama aynı zamanda bazı temel ders kitaplarını okumam gerektiğini söyleyen cevapları da aramıyorum. Bunu yaptım ve (en azından önemli miktarda) mantığı alıyorum. Ayrıca, (bu tür girişimler memnuniyetle karşılanacaktır) kapsamlı cevaplara ihtiyacım yok: Aksi takdirde zahmetli kod tek bir satır okuma için zarif bir yol sağlayan kısa cevaplar bile takdir edilecektir.
Sanırım bu sorunun bir kısmı: Fonksiyonel kodu doğrusal olarak okuyabilir miyim , bilirsiniz, soldan sağa ve yukarıdan aşağıya? Ya da kod sayfasında kesinlikle doğrusal olmayan spagetti benzeri kabloların zihinsel bir resmini oluşturmak zorunda mı? Ve eğer bunu yapmak gerekiyorsa , yine de kodu okumalıyız, peki doğrusal metni alıp spagetti'yi nasıl bağlarız?
Herhangi bir ipucu takdir edilecektir.
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