I am working on practicing booleans (where in the code below, I'm representing the number of times a fruit is counted, essentially that number will be what they can afford to the price, if that makes sense) and the code I am working on seems to be working, but the conditionals I have set are only returning as false and not as true and vice versa when they are swapped.
I'm just wondering if there is an issue with the logic that I currently have.
Here is the data that I have:
items = {
count: 100,
fruits: [
{ id: 'apple', price: 50 },
{ id: 'orange', price: 200 },
{ id: 'banana', price: 500 }
]
};
});
('returns true if the person can afford the item', function() {
const result = code.affordItem(items, 'apple');
expect(result).to.be.equal(true);
});
('returns false if person cannot afford the item', function() {
const result = code.affordItem(items, 'orange');
expect(result).to.be.equal(false);
Here is the code that I have:
function affordItem(items, itemId) {
if (items.count >= items.fruits.quantity && items.fruits.id === itemId) {
return true;
} else {
return false;
}
}
Any guidance would be much appreciated!
function affordItem(items, itemId) {
if (items.count >= items.fruits.length && items.fruits.id === itemId) {
return true;
} else {
return false;
}
}
Try this, i assumed you want to get the quantity of fruits so use array.length instead.
Related
Not sure how to approach this problem, but I want to see if two values are in the same 'line'
var inventory_needed = [
{ section: "hardware", supplies: "hammers" },
{ section: "plumbing", supplies: "pipes" },
{ section: "garden", supplies: "grass seeds" },
{ section: "cleaning supplies", supplies: ["hand sanitizer", "detergent"] },
{ section: "appliances", supplies: ["fridges", "dishwashers"] }
];
psuedocode of what I want to try to attempt
if(section.value && supplies.value in the same line) {
return true;
}
else {
return false;
}
//example 1
if("appliances" && "fridges" in the same line) {
return true; //would return true
}
else {
return false;
}
//example 2
if("plumbing" && "fridges" in the same line) {
return true;
}
else {
return false; //would return false
}
By in the same line, you seem to mean defined within the same object in the array. If that's correct, the way to do that is like this:
function inTheSameLine(section, supplies){
return inventory_needed.some(obj => {
return obj.section === section && (
obj.supplies === supplies || (
Array.isArray(obj.supplies) && obj.supplies.includes(supplies)
)
);
});
}
The JavaScript array some function returns true if any of the array elements satisfy the condition.
I apologise in advance for the title, I haven't found what I have been looking for while debugging but I may not know the correct terms to search for.
I have the following object:
const Game = {
user: {
tool: {
displayName: "shovel",
level: 0,
max: 1,
},
backpack: {
level: 0,
max: 10,
contents: {
ice: 5,
}
}
},
locations: {
lifePod: {
displayName: "Life Pod",
loseOxygen: false
},
icyPlain: {
displayName: "Ice Plain",
loseOxygen: true,
materials: {
type: "ice",
}
},
metalPlain: {
displayName: "Metal Plain",
loseOxygen: true,
materials: {
type: "metal",
}
}
}
};
I would like to use the following function to increase the count of the item in ice by 1. This works 100% of the time correctly, however when I try to use "metal" instead, it only allows a maximum of 2.
function mineResource(locationName) {
let newLocation = Game.locations[locationName];
if (Game.user.currentLocation != "lifePod" && newLocation.materials != undefined && backpackNotFull()) {
var alreadyInserted = false;
materialType = newLocation.materials.type; //ice
materialAmount = Game.user.tool.max; //1
let {backpack} = Game.user;
if (backpack.contents != null || backpack.contents != undefined) {
for (item in backpack.contents) {
if (item == materialType) {
Game.user.backpack.contents[materialType] += Game.user.tool.max;
alreadyInserted = true;
refreshValues();
} else if (alreadyInserted) {
null;
} else {
Game.user.backpack.contents[materialType] = materialAmount;
refreshValues();
}
};
};
};
}
I am confused by the fact that this function works fine with Ice but not Metal. As a test I changed:
contents: {
ice: 5,
}
to:
contents: {
ice: 5,
metal: 5,
}
And call Game.user.backpack.contents showed only {ice: 5} and calling contents.metal was undefined. I had definitely saved and refreshed. Unfortunately as I am a beginner I don't know what I don't know and it's hard to search for this. I have a put console logs underneath the "if (item == materialType) {" line and they were outputting but not increasing the counter.
If you want to see the whole code it's on http://oxygen.meddleso.me/main.js
EDIT: I did just remove Ice, and made metal the default with 5 and now Metal goes up by 1 normally, but if I add Ice like I was adding metal, Ice only goes up to 2 now.
When you add metal, but have ice, before adding metal you do
} else {
Game.user.backpack.contents[materialType] = materialAmount; // remove this line
refreshValues();
}
So when mining metal you do contents['metal'] = 1 (on ice loop) and later contents['metal'] += 1 (on metal loop)... Since you are looping over item set contents[item]. But I´m sure you would not want to set contents['ice'] = 1 either when mining metalPlain, so just remove this line.
Let's say I have a component which repeats with a v-for loop like so:
<hotel v-for="(hotel, index) in hotels"></hotel>
And my hotels array would look like so:
[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
]
How could I perform an action when my v-for loop encounters the property name set to true only on the very first time it encounters this truthy property?
I know I could probably cache a property somewhere and only run something once and not run again if it has been set but this does not feel efficient.
Use a computed to make a copy of hotels where the first one has an isFirst property.
computed: {
hotelsWithFirstMarked() {
var result = this.hotels.slice();
var first = result.find(x => x.name);
if (first) {
first.isFirst = true;
}
return result;
}
}
Just use computed source
HTML
<div v-for="(hotel, index) in renderHotels"></div>
JS
export default {
name: 'message',
data () {
return{
hotels:[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
] ,
wasFirst : false
}
},
methods:{
},
computed:{
renderHotels(){
return this.hotels.map((hotel)=>{
if(hotel.name && !this.wasFirst){
this.wasFirst = true;
alert('First True');
console.log(hotel);
}
})
}
}
}
Best way is to use filter function.
data() {
return {
firstTime: false,
};
},
filters: {
myFunc: function (hotel) {
if (hotel.name && !this.firstTime) {
//perform some action
this.firstTime = true;
}
}
}
<hotel v-for="(hotel, index) in hotels | myFunc"></hotel>
I have an Angular application that collects values of items for an invoice, I want to make sure only unique items are being added to this collection but am having no luck.
I am pushing 3 pieces of information to this collection: id, price, and type. I want to make sure there is nothing in the collection currently matching those 3 points.
// My container
$scope.invoice = {
items: [{
}]
}
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
if ($scope.invoice.items.indexOf(item.id) != $scope.item.id)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
// Trying to avoid collections like this
invoice: {
items:
[ { } , {
id: 25
price: 0
type: photo
} , {
id: 25
price: 0
type: photo
} ]
}
.filter is pretty much what you need.
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
var matches = $scope.invoice.items.filter(function(datum) {
return datum.id === $scope.item.id &&
datum.price === $scope.item.price &&
datum.type === $scope.item.type;
});
if (!matches.length)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
Semi-contrived JSFiddle
This is the solution I came up with to solve my problem, hopefully it helps someone else.
$scope.addPhoto = function () {
console.log('Withdrawing Photo: ' + $scope.item.id);
var newItemId = $scope.item.id;
var newItemPrice = $scope.item.price;
var newItemType = 'photo';
var matches = true;
// Make sure user hasnt already added this item
angular.forEach($scope.invoice.items, function(item) {
if (newItemId === item.id && newItemPrice === item.price && newItemType === item.type) {
matches = false;
$scope.message = 'You have already selected to withdraw this item!';
}
});
// add item to collection
if (matches != false) {
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
$scope.total += $scope.item.price;
$scope.message = 'Total Amount Selected';
}
};
YOu can simple pop opposite of push
array.splice(array.pop(item));
Im trying to write a function that 1. adds an item to an observable array and 2. replaces the item if it already exists in the array
self.addNotification = function (name, availability, note) {
//see if we already have a line for this product
var matchingItem = self.notifications.indexOf(name);
if (matchingItem !== undefined) {
self.notifications.replace(self.notifications()[index(matchingItem)],
new Notification(self, name, availability, note));
}
else {
self.notifications.push(new Notification(self, name, availability, note));
}
};
What am I doing wrong?
Regards Anders
Here is my answer: fiddle
Hit F12 in Chrome or use FireBug in FireFox to see console log output.
var notifications = {
notifs: [],
updateNotifications: function(notification) {
'use strict';
var matchIndex;
for (matchIndex = 0; matchIndex < this.notifs.length; matchIndex += 1) {
if (this.notifs[matchIndex].name === notification.name) {
break;
}
}
if (matchIndex < this.notifs.length) {
this.notifs.splice(matchIndex, 1, notification);
} else {
this.notifs.push(notification);
}
}
};
notifications.updateNotifications({
name: 'John',
available: false,
note: "Huzzah!"
});
notifications.updateNotifications({
name: 'Jane',
available: true,
note: "Shazam!"
});
notifications.updateNotifications({
name: 'Jack',
available: true,
note: "Bonzai!"
});
notifications.updateNotifications({
name: 'Jane',
available: false,
note: "Redone!"
});
console.log(notifications);
Well, Array.prototype.indexOf never returns undefined. Its either -1 (not found) or any number starting with 0 for the array index.