slice different arrays and return selected values - javascript

I am working on a problem. I do not know the right question to ask in order to solve this problem. I have gotten what seems to be the required results but the verification problem for the solution does not work. I am not sure if I am solving it correctly. Basically I am given an array and I have to filter out elements from that array by slicing certain ingredients.
question: "We only use the elements that the instruction tells us to. So, we need to create a slice of the given array of elements (taken from the beginning) to resemble only the elements we are using. If the instruction doesn't say anything, we only take the first element."
var hammerIngredients = ['iron', 'granite', 'copper'];
var spearIngredients = ['iron', 'granite', 'copper'];
var panIngredients = ['iron', 'granite', 'copper'];
take(hammerIngredients); // returns ['iron']
take(spearIngredients, 2); // returns ['iron', 'granite']
take(panIngredients, 3); // return ['iron', 'granite', 'copper']
"If the instruction says to use more than the elements listed, we use all the elements in the array. If the instruction says to use no elements, we return an empty array."
var plateIngredients = ['iron', 'granite', 'copper'];
take(plateIngredients, 0); // returns []
So I have tried to do the program and I have done the following. It appears to work, but when I try to verify it I get that it is invalid.
function take(ingredients, slicer) {
if (arguments.length === 1) {
slicer = 1;
}
if (ingredients === hammerIngredients){
return ingredients.slice(0, slicer);
} else if(ingredients === spearIngredients) {
return ingredients.slice(0,slicer);
} else if (ingredients === panIngredients) {
return ingredients.slice(0,slicer);
} else if (ingredients === plateIngredients) {
return ingredients.slice(0,slicer)
} else {
return;
}
}
And I have no idea why. Help please!

you have no logic for if the slicer parameter is 0, in which case you need to return an empty array.
Put this line in there and it should work, based on the requirements you gave:
if (slicer === 0) {
return [];
}

You code currently only works if one of those three exact arrays are used. Does the verification code create and use only those arrays?
Your code does not need to be tied to existing ingredient arrays. After setting the default slicer value you can just:
return ingredients.slice(0,slicer);

Related

Displaying only the first item from the localStorage data array

I am trying to build a board that should display the first number from the list but I can't find $.each alternative.
Currently, I have a piece of code that displays all items from the localStorage. Does anyone have an idea of jQuery function that would take an array as argument and callback only the first item? Similar to this one - $.each( array, callback ).
const clients = JSON.parse(localStorage.getItem("data"));
const odontologas = clients.Odontologas;
$.each(odontologas, function(i, item) {
if (item.Būsena === "Eilėje") {
$("#odontologasQueue").append(
`<p class="boardNumber">${item.EilėsNr}</p>`
);
} else {
$("#odontologasQueue").append(`<p class="boardNumber">000</p>`);
}
});
Just needed to add return false to if statement.
So either exit the loop when you find the match or use array.find
var first = odontologas.find(item => item.Būsena === "Eilėje")
// var first = odontologas.find(function(item) { return item.Būsena === "Eilėje" })
console.log(first)
Long story short, you want index of an entry? It's
odontologas.indexOf("Eilėje"); // equals -1 if element isn't found in the array

How to pass a function only after an entire array has been read and not for each element?

I'm trying to run a function when reading an array, but instead of running the function to each element, which I'm currently using forEach for, I want to make the script to read the entire array and then pass a function.
What I'm trying to say is this:
data.forEach(movie => {
// Log each movie's title
//console.log(movie.title);
// Check if the userWord matches
if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
alert("YES");
} else {
alert("NO").
}
});
Let's say my array is: array = ["Aa", "Ba", "Ca", "Da"];
If the user enters: a, then the script would alert("YES") four times, and I want to make it alert just once, at the end of the iteration.
For the same example, if the users enters: B, then the script would first alert("NO") once, then alert("YES"), then alert("YES") 2 times, and I want to make it just alert("YES")once, in the end.
Finally, if the users enters: Ferrari, then the script would alert("NO") four times, and I just want it to alert("NO") at the end.
I tried to make it very clear here, that's why the three "cases" of what is happening.
In the end, I want to know if there is a method that is kinda the opposite of the forEach or the common for. Something that just executes the function after reading the entire array.
Change the alert to a bool variable
Remove else (it would only overwrite any match)
if bool statement outside the loop to perform actions
if you want a list of the results, you should store the names in an array and outside of the loop - print.
see below:
Non-loop method:
data = ["test","hello", "hello1"];
search = "lo";
const matches = data.filter(movie => movie.includes(search));
alert(matches) //array of only matches - only has hello and hello 1
I don't know if there are performance gains against a loop... I suppose you could do a side by side comparison on a large dataset
Loop method:
var matches = "";
data.forEach(movie => {
// Check if the userWord matches
if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
matches += movie.title + "<br> ";
}
});
if (matches.length > 0)
{
document.getElementById("results").innerHTML = matches;
} else {
alert("No match found");
}
You'll see more customization on the first loop, but I think filtering data first is the way to go.
I think closest what you can get is some. Here is example
let data = ["test","hello", "hello1"];
let userWord = "el";
let res = data.some(movie => movie.toUpperCase().includes(userWord.toUpperCase()));
console.log(res) // prints true- means there was at least one "match", so you can alert
You could use the filter array function to filter array elements that match your criteria and then finally alert only if a match is found. Using this method you could get all the elements that have matched to your userWord. That is, the match array will contain all the possible matches.
var data = ['Aa', 'Bb', 'Cc', 'Dd'];
var flag = false;
var userWord = 'F'
var match = data.filter(movie => movie.indexOf(userWord) !== -1);
if(match.length)
console.log('YES');
else
console.log('NO');
If I understand the question correctly, I believe you want to execute something if a predicate matches at least one of the items in the array (correct me if I'm wrong). For that you can use the some method like so:
if (movies.some((movie) => movie.toUpperCase().includes(userWord.toUpperCase()))) {
alert('YES');
} else {
alert('NO');
}

Using Javascript Array Filter method to apply logic [duplicate]

I have search through quite a lot of questions here, but havent found one that i think fits my bill, so if you know of one please link to it.
I have an array that i want to search through for a specific number and if that number is in the array, i then want to take an action and if not then another action.
I have something like this
var Array = ["1","8","17","14","11","20","2","6"];
for(x=0;x<=Array.length;x++)
{
if(Array[x]==8)
then change picture.src to srcpicture1
else
then change picture.src to srcpicture2
}
but this will run the lenght of the array and end up checking the last element of the array and since the last element is not 8 then it will change the picture to picture2.
Now i can see why this happens, i just dont have any ideas as to how to go about checking if an array contains a specific number.
Thanks in advance.
What you can do is write yourself a function to check if an element belongs to an array:
function inArray(array, value) {
for (var i = 0; i < array.length; i++) {
if (array[i] == value) return true;
}
return false;
}
And the just do:
var arr = ["1","8","17","14","11","20","2","6"];
if (inArray(arr, 8)) {
// change picture.src to srcpicture1
} else {
// change picture.src to srcpicture2
}
It's a lot more readable to me.
For extra points you can add the function to the array prototype like so:
Array.prototype.has = function (value) {
for (var i = 0; i < this.length; i++) {
if (this[i] === value) return true;
}
return false;
};
And then the call would be
if (arr.has(8)) // ...
Pushing this even further, you can check for indexOf() method on array and use it - if not - replace it with the code above.
P.S. Try not to use Array for a variable name, since it's reserved for the actual array type.
use this
http://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf
ie version
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf#Compatibility
Why don't just you abort the loop when you find the right number :
for(x=0;x<=Array.length;x++)
{
if(Array[x]==8) {
//change picture.src to srcpicture1
break;
}
}
You could sort the array first then check the array only up to the point at which a number would be in the array, were it to exist.
If you have unique keys and a faster retrieval is what you care about a lot, you can consider using a map instead of an array (if there's a hard-bound case of using an array, then it won't work of course). If using a map, you just check "if( num in arr ) ".

Trouble showing alert after iterating through an array

I have an input field where the user inputs their zip code which I then attempt to match to a zip code within an array. While the following works, I need it to actually show an alert dialog once saying that zip code wasn't found, however, it current pops up a lot even if the zip code is in the list.
Here's my snippet:
_zipcodeBtn.onclick = function(){
var userZip = _zipcode.value;
for (var i = 0; i < zipcode_list.length; i++) {
if (zipcode_list[i] === userZip) {
console.log('works');
break;
} else {
alert("repeating");
}
}
};
I want it to check if their zip is available without it also repeating the else statement multiple times. Whats the best way to prevent this?
There's an easier way to find an item in an array, by referencing the array's indexOf() method (docs).
if (zipcode_list.indexOf(userZip) != -1) {
//found - do something
} else
alert('Zip not found!');
As Angel Politis shows, you can also use includes() if you literally just want to know whether an item is in an array, not its actual position within it.
Sidenote: it's important to check against -1 when using indexOf() because it returns the index at which the search is found - or -1 if it's not. If the search is found at the first key, this is 0, and 0 is a falsy value, which can catch people out sometimes when they do things like this:
var arr = [1, 2, 3];
if (arr.indexOf(1))
alert('success');
else
alert('failed');
You'd think the success alert would fire here, but actually it'll be the failure alert, because indexOf() in this case returns 0, and 0 is a falsy value when it's interrogated in a condition.
There's no need to use a loop here. You can just say:
if (!zipcode_list.includes(userZip)) alert("Doesn't work!");
If you must use a loop, then just set a flag by default to false and then, if the zip is found set it to true. Then you can check it outside the loop:
/* Create a flag and set it by default to false. */
var found = false;
/* Loop */
for (var i = 0, l = zipcode_list.length; i < l; i++) {
if (zipcode_list[i] === userZip) {
/* Set the flag to true and stop the loop. */
found = true;
break;
}
}
/* Check whether the zip was found in the array. */
if (found) console.log("Works!");
else alert("Doesn't work!");

Check if item already exists in json array by matching ID

So I've this shopping cart, as JSON.
[{"tuote":{"id":"2","name":"Rengas 2","count":16,"price":"120.00"}},{"tuote":{"id":"1","name":"Rengas 6","count":"4","price":"25.00"}},{"tuote":{"id":"4","name":"Rengas 4","count":"4","price":"85.00"}}]
Formatted here.
So, I want to prevent from having the same value in there twice, and match them by their ids.
This is my current solution (buggy as a cockroach, doesn't really do the job), as the only time it works is when the matching value is first in the JSON string.
for (var i = 0; i < ostoskori.length; i++) {
if (ostoskori[i].tuote.id == tuoteID) {
addToExisting(tuoteID, tuoteMaara); //this doesn't matter, it works.
break //the loop should stop if addToExisting() runs
}
if (ostoskori[i].tuote.id != tuoteID) {
addNew(tuoteID, tuoteNimi, tuoteMaara, tuoteHinta); //this doesn't matter, it works.
//break
//adding break here will stop the loop,
//which prevents the addToExisting() function running
}
}
ostoskori is the json if you're wondering. As you can probably see, for each item the JSON has inside it, the more times addNew() will run.
So basically, if the JSON has a value with the same id as tuoteID, addToExisting() should run. If the JSON doesn't have a value same as tuoteID, run addNew().
But how?
You could use some to check if the id already exists. The beauty of some is:
If such an element is found, some immediately returns true.
If you're catering for older browsers there's a polyfill at the bottom of that page.
function hasId(data, id) {
return data.some(function (el) {
return el.tuote.id === id;
});
}
hasId(data, '4'); // true
hasId(data, '14'); // false
So:
if (hasId(data, '4')) {
addToExisting();
} else {
addNew();
}
Fiddle

Categories

Resources