ამ სტატიაში მინდა განვიხილო fp მიდგომა, ანუ როგორი იცვლება მიდგომა პროცედურულ ან oop სთან მიმართებაში, ამას განვიხილავთ მარტივი კოდის მაგალითით.

მაგალითად გვაქვს პროდუქტების სია კალათაში

var cart = [
	{
		name: 'შავი მაიკა',
		price: 25,
	}, {
		name: 'მწვანე მაიკა',
		price: 19
	}
];

და გვინდა გავიგოთ ფასების ჯამი

ამას პროცედურულად გავაკეთებდით ასე

var total = 0;
for(var i in cart) {
	total += cart[i].price;
}

ანუ ვქმნით ცვლადს total შემდეგ გავრბივართ კალათაში და total-ს ვმატებთ თითოეულის ღირებულებას

fp ვერსიაში ლოგიკა განსხვავებულია

var total = cart
	.map(function(obj) {return obj.price})
	.reduce(function(a, b) {return a + b});

ანუ map-ით კალათაში არსებულ პროდუქტების სიას გარდავქმნით ფასების სიათ და შემდეგ reduce-ით ფასებს ერთმანეთს ვუმატებთ

უფრო fp-ური ვერსია (ramda-ს გამოყენებით)


var total = R.pipe(
	R.map(R.prop('price')),
	R.reduce(R.add, 0)
)(cart);

აქაც ზუსტად იგივე ხდება რაც პირველ fp მაგალითში მაგრამ ვიყენებთ function composition-ს (დეტალებს ცოტახანში ავხსნი)

ასევე შეგვიძლია სხვანაირადაც გავაკეთოთ იგივე

var total = R.pipe(R.plunk('price'), R.sum)(cart);

აქაც იგივეს ვაკეთებთ რაც წინა მაგალითში იყო R.plunk('price') იგივეა რაც R.map(R.prop('price')) და R.sum იგივეა რაც R.reduce(R.add, 0)

ახლა კი როგორ მუშაობს function composition

დავიწყოთ R.map იდან

ეს არის ფუნქცია რომელიც ღებულობს ორ პარამეტრს

პირველი პარამეტრი პირობითად fn არის ფუნქცია

და მეორე პარამეტრი პირობითად arr არის მასივი

map აბრუნებს ახალ მასივს რომელშიც ყველა ელემენტი არის ამ ელემენტის fn ში ჩაწოდების შემდეგ მიღებული შედეგი

ანუ როგორც მაგალითად 5x3 არის 3+3+3+3+3

ასევე R.map(fn, [1, 2]) არის [fn(1), fn(2)]

მაგრამ კოდის მაგალითში map-ს გადაეწოდება მხოლოდ ერთი პარამეტრი რის საშვალებასაც იძლევა currying-ი ანუ მაგალითად გვაქვს ფუნქცია add

function add(a, b) {
	return a + b;
}

თუ ამ ფუნქციას გამოვიძახებთ და გადადვაწვდით მხოლოდ ერთ პარამეტრს მივიღებთ ერორს (უფრო სწორეთ მივიღებთ NaN ს რაც იქნება გადაწოდებული პარამეტრის undefined ზე მიმატების შედეგი)

ახლა იგივე ფუნქცია currying ით

var add = R.curry(function(a, b) {
	return a + b;
});

თუ ამ ფუნქციას გამოვიძახებთ და გადადვაწვდით მხოლოდ ერთ პარამეტრს მაგალითად ასე

var addOne = add(1);

ჩვენ მივიღებთ ფუნქციას რომელიც ელოდება მეორე პარამეტრს ანუ addOne(3) იგივეა რაც add(1, 3) ან add(1)(3)

ახლა დავუბრუნდეთ map-ს რომელიც იყენებს currying-ს, ამის წყალობით ჩვენ შეგვიძლია რომ მას გადავაწოდოთ ფუნქცია და ის დაგვიბრუნებს მაპს რომელსაც უკვე აქვს ფუნქცია და ელოდება მასივს

აქედან გადავიდეთ R.prop ზე რომელიც ძალიან მარტივ რამეს აკეთებს.

მას გადაეწოდება ორი პარამეტრი: სტრიქონი პირობითად propName და ობიექტი პირობითად obj.

ამ ფუნქციასაც აქვს currying რაც იმას ნიშნავს რომ თუ მას გამოვიძახებთ მარტო propName ით

ის დაგვბრუნებს ფუნქციას რომელიც ელოდება obj-ს

თუ ამას გამოვიყენებთ map თან ერთად და მაპს ჩავაწვდით prop-ის მიერ დაბრუნებულ ფუნქციას ასე

var toPrices = R.map(R.prop('price'));

მივიღებთ ფუნქციას რომელიც ელოდება მასივს რომელშიც ყველა ობიექტს ჩაანაცვლებს ამ ობიექტზე არსებული პარამეტრის price-ის მნიშვნელობით ამგვარად მივიღებთ ფასების მასივს

ფასების მასივიდან გადავდივართ ჯამის დათვლაზე, რასაც ვაკეთტებთ reduce-ით.

reduce-ს გადაეწოდება სამი პარამეტრი

ფუნქცია პირობითად fn

ერთი ნებისმიერი ტიპის ცვლადი პირობითად a

და მასივი პირობითად arr

რედუსი გარბის მასივში და fn ს იძახებს a თი და მიმდინარე მასივის ელემენტით დაბრუნებული მნიშვნელობა ენიჭება a-ს და შემდეგ გამოიძახება მომდევნო ელემენტი სანამ ბოლოში არ გავა, ბოლოს ბრუნდება a

ანუ თუ reduce-ს გამოვიძახებთ ასე

var sum = R.reduce(R.add, 0);

მივიღებთ ფუნქციას რომელიც მასივის მნიშვნელობების ჯამს ითვლის.

reduce-ის a თავიდან უდრის 0 შემდეგ ყველა მასივის ელემენტი ემეტება a-ს და ბოლოს ბრუნდება a

R.add იგივეა რაც add ფუნქცია რომელიც უკვე ავღწერეთ უბრალოდ ორ გადაწოდებულ პარამეტრს ერთმანეთს უმატებს და ჯამს აბრუნებს

დაგვრჩა R.pipe

pipe ღებულობს N რაოდენობის პარამეტრებს (ფუნქციებს)

და აბრუნებს ფუნქციას რომელიც ელოდება ერთ მნიშვნელობას რომელმაც უნდა გაირბინოს გადაწოდებულ ფუნქციაბში

ანუ


var total = R.pipe(
	R.map(R.prop('price')),
	R.reduce(R.add, 0)
)(cart);

იგივეა რაც


var prices = R.map(R.prop('price'))(cart);
var total = R.reduce(R.add, 0)(prices);

და

var total = R.pipe(R.plunk('price'), R.sum)(cart);

იგივეა რაც

var total = R.sum(R.plunk('price', cart));

იმედი მაქვს საინტერესო სტატია იყო და დაგაინტერესათ fp-ს შესწავლამ

ცნობარი: