Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am having a hard time trying to get this right. I would be glad if someone could help me get a solution for this.
0: Object
Name: Ria
Age: 27
Sex: Female
1: Object
Name: Brian
Age: 23
Sex: Male
2: Object
Name: Rick
Age: 32
Sex: Male
Here is the array of objects. I am passing a user entered value. for e.g. I ask the user to enter the name. Once entered, i need to check in the above array of objects, if the Name is present in the array of objects.
I tried a variety of solutions using foreach, basic array itereation and i couldnot find a way.
Here is what i tried at the last...
var result = false;
function search(nameKey, myArray) {
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].Name === nameKey) {
return true;
}
}
}
result = search($scope.data.name, checkdatabase);
Here, checkdatabase is the array of objects and $scope.data.name is the user entered value. I am expecting the value of result as true when user is present in database or else result as false which is defined initially.
What you need is Array.prototype.some:
result = myArray.some(function(user) { return user.name === $scope.data.name; });
BTW, this is just a suggestion: I would store an index of user names and use Array.prototype.indexOf.
Whenever you add an user, you can add the name to an array:
var userNameIndex = [];
var users = [];
users.push(user);
// I've called .toLowerCase() so the index isn't case sensitive
userNameIndex.push(user.Name.toLowerCase().trim());
...and you can check if the user has been already added as follows:
// I've called .toLowerCase() to perform a case insensitive search
var result = userNameIndex.indexOf($scope.data.name.toLowerCase().trim()) > -1;
It should perform better if you're retrieving a lot of users.
I am expecting the value of result as true when user is present in
database or else result as false which is defined initially.
Yes, but note that calling search sets the variable result again. That is, the initial false is never preserved.
To extend Matias' answer, some is great for the job as long as you don't need the item that matches your predicate. some accepts a context as a second argument:
result = myArray.some(function(user) {
return user.name === this.name;
}, $scope.data); //pass $scope.data as this
If your want to keep track of the item that matches the predicates, you have several options: Create an object of indexes or iterate over the array using forEach or while
var index = myArray.map(function(item) {
return item.name;
}).indexOf(nameKey);
var item = myArray[index];
var l = myArray.length;
var found = false;
while(!found && l--) {
found = myArray[l].name === nameKey;
}
var item = myArray[l];
use lodash.js. you can filter the array with given parameter.
For Example :
var givenJson ={ Name: Ria,Age: 27,Sex: Female};// this is the whole array
var response= _.filter(givenJson, function(data){
return data.name == "Ria";
});
if(response != null && response != undefined){
return true;
}
Related
This question already has answers here:
Why does JavaScript map function return undefined?
(13 answers)
Closed 3 years ago.
Simple array declaration:
let sodas = ["Sprite", "Coke", "Mountain Dew", "Dr. Pepper", "Sunkist"];
I want to use .map() function to create a new array containing sodas only owned by the CocaCola Company, and then display this new array in the console -
let cocacola_sodas = sodas.map(soda => {
if ((soda == "Coke") || (soda == "Sprite")) {
return soda;
}
})
console.log(cocacola_sodas);
This code seems to work, though I'm not sure why it is returning 5 new elements into cocacola_sodas array when only 2 of them should be returned (coke and sprite). The array will display ["Sprite", "Coke", undefined, undefined, undefined]. Why is it returning undefined values?
#awoldt, to help you understand what is actually happening, Array.prototype.map will always return the same number of elements from the input array to a new array.
so best way to think about it is you give map an array with x elements, regardless of what you do to those elements inside the block you pass to map, it will always return X # of elements in the new array.
As was suggested, something like filter/reduce will return a new array with just the elements that meet the criteria you set out int he block passed to those helpers
you can read more about map and all the Array.prototype.methods at MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Use filter instead of map. It was made or use in situations like this. As pointed by other answers map will always return the same number of elements as present in the input array
let sodas = ["Sprite", "Coke", "Mountain Dew", "Dr. Pepper", "Sunkist"];
let cocacola_sodas = sodas.filter(soda => {
if ((soda == "Coke") || (soda == "Sprite")) {
return soda;
}
})
console.log(cocacola_sodas);
To elaborate on #ellipsis answer:
The reason filter is better here is because it is generating a new array of items not filtered out of the original array.
The reason map is giving you the results you see are because it's not filtering, but changing each element and giving it to the result array. I think a code example would help to clarify.
Map might look something like this under the hood:
var array = ['one', 'two', three];
var mapFunc = function(item) {
if(item == 'two')
return item;
};
var mappedArray = [];
for(var i = 0; i < array.length; i++)
mappedArray.push(mapFunc(array[i]));
Obviously the above is simplified to be clear, but as you can see the mapped array will have as many items in it as the original array. Since you return nothing in the case item doesn't equal two then you return undefined hence why you have the extra items in your example.
The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.
let sodas = ["Sprite", "Coke", "Mountain Dew", "Dr. Pepper", "Sunkist"];
let cocaCola = ["Coke","Sprite"];
let cocacola_sodas = sodas.filter(soda => cocaCola.includes(soda))
console.log(cocacola_sodas);
This question already has answers here:
How to get a key in a JavaScript object by its value?
(31 answers)
Closed 7 years ago.
I do have a javscript object containing a product name and the corresponding product code. The code is unique.
var products = {
"Pineapple":38,
"Apple":110,
"Pear":109
};
If i want to know the code for a product i can just do
var pineapplecode = products["Pineapple"];
How do I check if there is a product for a given number and if print it ? Or do I have to/should I change the way the data is saved ?
I think the shortest way would be:
var prodCode = 38;
var result = Object.keys(products)
.filter(function(k) { return products[k] == prodCode; })[0];
// result == "Pineapple"
See MDN
I guess you are basically asking if I can check the other way round, i.e. check for key by passing value.
Yes you can,
Either by iterating through all the key and values, check if the value is existing and finally return the key if the value exists
change the way you save the data, index it by product number rather than product name
here is the code to convert one form to another
var newProducts = {};
for( var prodName in products )
{
newProducts[ products[ prodName ] ] = prodName;
}
console.log( newProducts );
And here is the code to check a specific value
var valueToCheck = "110";
var prodNameToFind = "";
for( var prodName in products )
{
if ( products[ prodName ] == valueToCheck )
{
prodNameToFind = prodName;
}
}
console.log( prodNameToFind );
Just iterate over the keys and the properties values and break the iteration if found with Array.prototype.some()
The some() method tests whether some element in the array passes the test implemented by the provided function.
var products = {
Pineapple: 38,
Apple: 110,
Pear: 109
};
function getProduct(code) {
var product;
Object.keys(products).some(function (k) {
if (products[k] === code) {
product = k;
return true;
}
});
return product;
}
document.write(getProduct(109));
Title is pretty much self explanatory...
I want to be able to find duplicated values from JavaScript array.
The array keys can be duplicated so I need to validate only the array values.
Here is an example :
var arr=[
Ibanez: 'JoeSatriani',
Ibanez: 'SteveVai',
Fender: 'YngwieMalmsteen',
Fender: 'EricJohnson',
Gibson: 'EricJohnson',
Takamine: 'SteveVai'
];
In that example:
the key is the guitar brand
the value is the guitar player name.
So:
If there is duplicated keys (like: Ibanez or Fender) as on that current example that is OK :-)
But
If there is duplicated values (like: EricJohnson or SteveVai) I'm expecting to get (return) that error:
EricJohnson,SteveVai
You can't have associative arrays in Javascript. You can create an array of objects, like:
var arr=[
{Ibanez: 'JoeSatriani'},
{Ibanez: 'SteveVai'},
{Fender: 'YngwieMalmsteen'},
{Fender: 'EricJohnson'},
{Gibson: 'EricJohnson'},
{Takamine: 'SteveVai'}
];
Then you'll need a for...in loop to go over every object in the array, create a new array of values and check that for duplicates, which is also not very straightforward - basically you'll want to sort the array and make sure no value is the same as the one after it.
var arrayOfValues = [];
arr.forEach(function(obj){
for(var prop in obj)
arrayOfValues.push(obj[prop]);
});
arrayOfValues.sort(); // by default it will sort them alphabetically
arrayOfValues.forEach(function(element,index,array){
if(array[index+1] && element==array[index+1])
alert("Duplicate value found!");
});
First of all, object keys can not be repeated.
This means that:
({
"Fender": "Jim",
"Fender": "Bob"
})["Fender"]
Would simply return: "Bob".
However, I did make a code that could allow you to find duplicates in values, but as I said, the key will have to be unique:
var arr = {
Ibanez: 'EricJohnson',
Fender: 'YngwieMalmsteen',
Gibson: 'EricJohnson',
Takamine: 'SteveVai',
"Takamine2": 'SteveVai'
};
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
var track = [];
var exists = [];
for (var val in arr) {
if (contains(track, arr[val])) {
exists.push(arr[val]);
} else {
track.push(arr[val])
}
}
alert(exists)
You can see it working here: http://jsfiddle.net/dr09sga6/2/
As others have commented, the example array you provided isn't a valid JavaScript array. You could, however, keep a list for each guitar type:
var mapping = {
Ibanez: ['JoeSatriani','SteveVai'],
Fender: ['YngwieMalmsteen','EricJohnson']
Gibson: ['EricJohnson'],
Takamine: ['SteveVai']
];
Or a list of each guitar/musician pair:
var pairs = [
['Ibanez','JoeSatriani'],
['Ibanez','SteveVai'],
['Fender','YngwieMalmsteen'],
['Fender','EricJohnson'],
['Gibson','EricJohnson'],
['Takamine','SteveVai']
];
Your solution is going to depend on which pattern you go with. However, in the second case it can be done in one chained functional call:
pairs.map(function(e) {return e[1]}) // Discard the brand names
.sort() // Sort by artist
.reduce(function(p,c,i,a){
if (i>0 && a[i]==a[i-1] && !p.some(function(v) {return v == c;})) p.push(c);
return p;
},[]); //Return the artist names that are duplicated
http://jsfiddle.net/mkurqmqd/1/
To break that reduce call down a bit, here's the callback again:
function(p,c,i,a){
if (i>0
&& a[i]==a[i-1]
&& !p.some(function(v) {
return v == c;
}))
p.push(c);
return p;
}
reduce is going to call our callback for each element in the array, and it's going to pass the returned value for each call into the next call as the first parameter (p). It's useful for accumulating a list as you move across an array.
Because we're looking back at the previous item, we need to make sure we don't go out of bounds on item 0.
Then we're checking to see if this item matches the previous one in the (sorted) list.
Then we're checking (with Array.prototype.some()) whether the value we've found is ALREADY in our list of duplicates...to avoid having duplicate duplicates!
If all of those checks pass, we add the name to our list of duplicate values.
I have a select field which on change I get the value. As I am looping through the select values I want to detect if it matches the value I have if it does I also want to check if the object contains a flag===true I wrote in. All I keep getting is the amount of items in the array and whatever the last one's flag is what the final value is.
array[
object{
value: fromSelectChange //if matches && flag is set to true stop looping
flag: true
}
]
assuming array is you array
var array = [
{value: fromSelectChange, flag: true},
. . . // others
];
just use
function match(arr, value){
var totalOk = 0;
arr.every(function(el){
if(el.flag && value == el.value){
totalOk++;
}
});
return totalOk;
}
alert(match(array))
My First reaction would be to throw it all into a for in loop. I usually find it one of the easier ways to see if something iterating on arrays will work.
var fromSelectChangeReturn;
for (index in array) {
if (array[index].fromSelectChange == value && array[index].flag) {
fromSelectChangeReturn = array[index].fromSelectChange;
Break;
}
}
For in MDN page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
I've searched and found a few similar-but-not-quite answers.
I have an array SongList (showing 2 items for brevity...) - the first pair is a key, the second pair is some JSON.
SongList={
song_1:{title:"title of first song",artist:"the artist",mp3:"http://mysite/song1.mp3"},
song_2:{title:"title of second song",artist:"the artist",mp3:"http://mysite/song2mp3"}
...
};
I would like to be able to retrieve the key (song_1 or song_2) given the title in the value.
I will be looping through a temporary array of i items, each item in this array would have a match in SongList and I would save the key (song_1, song_2) in a final array.
You don't have an array, you have an object, containing more objects. Use for in
function findTitle(title) {
for (var key in SongList) {
if (SongList[key].title == title) return key;
}
return false;
}
And then call it!
findTitle("title of first song"); //returns "song_1"
findTitle("BNOT MEEEEEE"); //returns false
Here is an example.
var one = {
a: {b:"MightyMouse", d:2},
b: {b:"MickeyMouse", d:4},
c: {b:"Superman", d:6}
};
for (outerkey in one) {
if (one[outerkey].b === "Superman") {
console.log ("Outerkey = " + outerkey);
}
}
Assuming you are looking for Superman, this prints as expected c.
Thanks everyone, I realize my understanding of Arrays v. Objects was an issue which obviously hindered my Google-Fu. I hope it's ok to post the answer I finally arrived at via guidance here:
(SongList object is described in question above)
This is the eventual function I arrived at for saving the keys of the playlist SongList:
$("#save_playlist_as_keys").click(function() {
var keys = []
for(var i=0; i<myPlaylist.playlist.length; i++){
var playItem = (myPlaylist.playlist[i].title); //this returns the names of the tracks
for (var k in SongList){
if(SongList[k].title == playItem) keys.push(k);//this matches track name to keys
}
}
localStorage.setItem('storedKeys',keys);
});
This seems to be doing what I want for now.