Задачи от изпита по JS OOP


0

Не мога да разбера защо не минава последния тест:1) Regular test 13: expect `cart.getInfo()` to return an object with `product` array with 2 products and `totalPrice` equal
 to `20`, when `cart.products` has products 

Ето и кода:

function solve() {
    class Product {
        constructor(productType, name, price) {
            this._productType = productType;
            this._name = name;
            this._price = price;
        }
        get productType() {
            return this._productType;
        }
        set productType(value) {
            if (!typeof(value) === 'string') {
                throw "Product type must be a string";
            }
            this._productType = value;
        }
        get name() {
            return this._name;
        }
        set name(value) {
            if (!typeof(value) === 'string') {
                throw "Name must be a string";
            }
            this._name = value;
        }
        get price() {
            return this._price;
        }
        set price(value) {
            if (isNaN(value) && value > 0) {
                throw "Price must be a number";
            }
            this._price = value;
        }
    }

    class ShoppingCart {
        constructor() {
            this.products = [];
        }
        add(product) {
            this.products.push(product);
            return this;
        }
        remove(product) {
            let itemToRemove = null;
            if (this.products.length < 1) {
                throw "Shopping Cart is not containig any products";
            }
            for (let i = 0; i < this.products.length; i += 1) {
                if ((this.products[i] === product)) {
                    itemToRemove = i;
                    break;
                }
            }
            if (itemToRemove === null) {
                throw "Shopping Cart is not contained the product";
            }
            this.products.splice(itemToRemove, 1);
        }
        showCost() {
            let costs = 0;

            for (let i = 0; i < this.products.length; i += 1) {
                costs += this.products[i]._price;
            }
            return costs;
        }
        showProductTypes() {
            let productTypes = new Set();
            for (let i = 0; i < this.products.length; i += 1) {
                productTypes.add(this.products[i]._productType);
            }
            return Array.from(productTypes).sort();
        }
        getInfo() {
            let obj = {};
            let info = {};
            let totalPrice = 0;
            let products = [];
            let sortedProducts = this.products;

            function compare(a, b) {
                if (a._name < b._name)
                    return -1;
                if (a._name > b._name)
                    return 1;
                return 0;
            }
            sortedProducts.sort(compare);
            var count = {};
            for (let i = 0; i < sortedProducts.length; i += 1) {
                if (count[sortedProducts[i]._name]) {
                    count[sortedProducts[i]._name]++;
                } else {
                    count[sortedProducts[i]._name] = 1;
                }

            }

            function search(key) {
                var obj = sortedProducts.find(function(obj) {
                    return obj.name === key;
                });
                return obj._price;
            }
            for (var key in count) {
                if (count.hasOwnProperty(key)) {
                    let quantity = 0;
                    obj.name = key;
                    quantity = count[key];
                    obj.totalPrice = (search(key) * quantity);
                    obj.quantity = count[key];
                    products.push(obj);
                    obj = {};
                }
            }

            for (let total of products) {
                totalPrice += total.totalPrice;
            }
            info.totalPrice = totalPrice;
            info.products = products;
            return info;
        }
    }
    return {
        Product,
        ShoppingCart
    };
}

module.exports = solve;




Отговори



1

Това е моето решение(на този метод) дано да ти е полезно

getInfo() { if (this._products.length < 1) { return { totalPrice: 0, products: [] } } let products = []; this._products.forEach(function(product) { if (products.indexOf(product.name) < 0) { products.push(product.name); } }); return { totalPrice: this.showCost(), products: products } }

Иначе забелязах че взимаш цената когато продукта се повтаря(името на продукта е същото но цената различна) и мисля че там ти е грешката.

Това е конкретния тест който ти гърми:

cart.products.push(new result.Product("Type 1", "Pr 1", 1)); cart.products.push(new result.Product("Type 1", "Pr 1", 2)); cart.products.push(new result.Product("Type 1", "Pr 1", 2)); cart.products.push(new result.Product("Type 1", "Pr 1", 2)); cart.products.push(new result.Product("Type 1", "Pr 1", 3));

Както виждаш иманата са еднакви но цените различни.

Решението доста простичко :D просто си преизползвай горния метод:

info.totalPrice = this.showCost(); и теста минава :)

EDIT:

Колегата е прав наистина не съм обърнал внимание (пак не съм си дочел условието като хората :D)

Ето така вече е коректно поведението

getInfo() { if (this._products.length < 1) { return { totalPrice: 0, products: [] } } let uniqueProducts = [] this._products.forEach(function(product) { let index = 0; uniqueProducts.forEach(function(uniqueProduct) { if (uniqueProduct.name === product.name) { uniqueProduct.quantity += 1; uniqueProduct.totalPrice += product.price; } else if (index === uniqueProducts.length - 1) { uniqueProducts.push({ name: product.name, quantity: 1, totalPrice: product.price }) } }, index) if (uniqueProducts.length < 1) { uniqueProducts.push({ name: product.name, quantity: 1, totalPrice: product.price }) } }); return { totalPrice: this.showCost, products: uniqueProducts } } }


от kiko0o7 (472 точки)


0
По какво се търси тогава уникален продукт, освен в случая само по име? Благодаря за отговора 


2
Колега, не трябва ли в масива от products да push-ваш продукти (обект), които имат totalPrice, quantity и name? 

  • products: Groups products by their name
    • For each unique product name there creates an element:
      • The name of the products
      • Their total cost
      • The quantity of products with this name in the ShoppingCart instance
  • totalPrice: The total price of all products in this ShoppingCart instance

@Neviana_Michaleva трябва да групираш всички продукти, които имат еднакво име, като ги "групираш" в обект с property-та: name, quantity и totalPrice. Търси се само по име.

от Ilian_Iliev_2 (1043 точки)



2

Ето мойто.

/* globals module */ "use strict"; function solve(){ class Product{ constructor(productType, name, price){ this.productType = productType; this.name = name; this.price = price; } get productType(){ return this._productType; } set productType(type){ if(typeof type !== 'string'){ throw "Ptoduct type must be a string."; } this._productType = type; } get name(){ return this._name; } set name(name){ if(typeof name !== 'string'){ throw "Name must be a string."; } this._name = name; } get price(){ return this._price; } set price(price){ if(typeof price !== 'number'){ throw "Price must be a number."; } this._price = price; } } class ShoppingCart { constructor(){ this.products = []; } add(product){ if(!(product instanceof Product)){ throw "Must pass a product-like object."; } if(Array.isArray(product[0])){ product = product[0]; } if(product.length === 0){ throw "No products added."; } this.products.push(product); return this; } remove (product){ if(!(product instanceof Product)){ throw "Must pass a product-like object."; } if(this.products.length === 0){ throw "Products are empty."; } if(this.products.indexOf(product) > -1){ this.products.splice(this.products.indexOf(product), 1); } else { throw "No such product;"; } } showCost(){ if(this.products.length === 0){ return 0; } let sum = 0; this.products.forEach(function(x) { sum += x.price; }); return sum; } getUniqueProductNames(){ let uniq = {}; this.products.forEach(x => uniq[x.name] = true); return Object.keys(uniq); } showProductTypes(){ let uniq = {}; this.products.forEach(x => uniq[x.productType] = true); return Object.keys(uniq).sort(); } getInfo(){ if(this.products.length === 0){ return { products: [], totalPrice: 0 }; } else { return { products: this.getUniqueProductNames().map(x => x === {}), totalPrice: this.showCost() }; } } } return { Product, ShoppingCart }; } module.exports = solve;


от Kantonov (60 точки)


1
Срам ме е да си призная, но не успях да подкарам тестовете. Сигурно съм единствената и все още ми е интересно как да го направя... на мен ми излиза грешка: "SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode. "

от grozdanova (322 точки)

0
Дай линк към кода

от nProdanov (587 точки)



1

Здравей, 

Само да вметна:

let sortedProducts = this.products;

по този начин само реферираш колекцията и след като я сортираш и this.products ще е сортиран.(това може би не пречи на задачата, но едва ли е което искаш) -> По - добре е да използваш slice().

А относно totalPrice:

функцията search(key), понеже ползва find() - връща първия срещнат, който отговаря на условието. Така  totalPrice за съответния продукт при теб става "цената на първия срещнат" * "количеството". Като цяло малко сложно си го направила и лесно може да се обърка човек. Ще добавя и моето решение, в случай, че на някой му е интересно. :)

Ето линк към 2-те задачи от изпита,


от nProdanov (587 точки)


0
Е, явно толкова си мога... Икономист съм и за мен не може да има два еднакви продукта с различни цени. Благодаря за отговора 



1

Ето го и моето решение на този метод :)

http://pastebin.com/Q0iFau86


от Merhatt (1406 точки)


2
Това е истинско решение на getInfo() метода. Ако публикуваните по-нагоре решения дават пълния брой точки значи тестовете не са пълни.

от marks (354 точки)

1

Добро решение. дали тези 2 реда:

names[this.products[i].name].price = 0;

names[this.products[i].name].quantity=0;

не е по-добре да са:

names[this.products[i].name].price = this.products[i].price;

names[this.products[i].name].quantity=1;

Струва ми се иначе бихме пропуснали цената и количеството на първия срещнат елемент.


от messenger (552 точки)



0

Някой да има идея защо този валидатор за mana не работи

manaValidator: function (mana) { if (parseInt(mana) !== mana || mana < 1) { throw new Error(ERROR_MESSAGES.INVALID_MANA); } }

Стрингове си минават като валидни. Това е решението ми на задачата


от magadisho (823 точки)


0

подозирам, че минават като NaN.

Пробвай така:

if (typeof value !== 'number') { throw "Count must be a positive integer number!"; } if (value !== parseInt(value, 10)){ throw "Count must be a positive integer number!"; }

https://ariya.io/2014/05/the-curious-case-of-javascript-nan


от messenger (552 точки)


1
Здравейте, тъй като не намирам решения на задачите от проведения изпит, моля някой от колегите да сподели своите. Лично на мен ще ми бъдат от голяма полза. :)



1
Ето тук един от колегите със 196 точки си е споделил решенията - решения

от tabula (2134 точки)

1
1ва  2ра. Втора обаче е за 93 точки.