Looping through array until value is found and then breaking - javascript

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

Related

if array contains duplicate, merge both values as one

I've got an array that looks like:
Is there a way that when another object "AAPL" gets added to the array, the fees and amount gets added and AAPL stays one object in the array?
Thank you in advance!
I wouldn't want to assume that "AAPL" is always within the array.
Check first if the new item is within the array. If not, I will return and end the call (but you may wish to append this to the array instead as it is a new item).
If it is, replace the current object (or parts of the object, in this case I have done just fees & amount)
function addPortfolioItem(item) {
const index = returnPortfolioHoldingIndex(item);
if (index = -1) {
// Returning if not found - You may wish to append to the array as mentioned above
return;
} else {
// Overwrite the object within the array with the new object
portfolioHoldings[index].fees = item.fees;
portfolioHoldings[index].amount = item.amount;
}
}
function returnPortfolioHoldingIndex() {
const tickerSymbolToSearch = "AAPL";
return portfolioHoldings.findIndex(item => item.ticker_symbol === tickerSymbolToSearch);
}
First identify the entry then just add another integer to the value.
It depends on how you are updating that object now - if it's always in 0 position then just portfolioHoldings[0][amount] += number;
if not, then loop through all and check if ticker_symbol == AAPL, then update that array value, by adding needed amount.

Loop through multiple values and remove from array

I have an event that attempts to remove items from a list. Currently trying to use splice to remove them from the array of objects. I need to use a function that acutally uses the original array. As I want so see the change happen live in the frontend. The code below works to a certain extent, but only seems to remove some items per click.
Controller
$scope.clearAlerts = function(type) {
var array = [];
for (let item of $scope.notifications) {
if (item.read && type == 'seen') {
notifications.clearAlerts(item.watching_id);
//console.log(item.watching_id)
}
if (!item.read && type == 'notseen') {
notifications.clearAlerts(item.watching_id);
//console.log(item.watching_id) - This returns 8 items
}
}
}
Service
this.clearAlerts = function(watchingId = null) {
// Remove notifications
this.notifications.forEach((item, index, object) => {
if (item.watching_id === watchingId) {
//remove alerts from dom
object.splice(index, 1); - This only removes 2 or 3 per click
index--;
// update database
//return api.request('GET', 'notification/' + watchingId + '/clear', {watching_id: watchingId});
}
});
}
Any help on this would be much appreciated. Thanks
So if you were to use an object instead of an array where the keys of the object were say the ID you are watching then your service function should look something like this...
this.clearAlerts = function(watchingId = null) {
delete this.notifications[watchingId];
}
Much simpler, so the idea is that instead of using an array as in [object, object], us an object that is mapped out something like so
{
id1: object,
id2: object,
...
}
where id1, and id2 are actually taken from watching_id which you defined
As for the reason why your alerts aren't removed accurately is because you are mutating the array you are looping through.
Here is an example
const notifications = [
{
watching_id: 1
},
{
watching_id: 2
},
{
watching_id: 3
},
{
watching_id: 4
}
];
notifications.forEach((item,index, arr) => {
if (item.watching_id > 0) {
arr.splice(index, 1);
}
})
In this example at first sight it can seem that all items are going to be deleted, but that is not the case.
When the index is 0, you delete the first item, and after deletion you have an array with 3 items, so on the second iteration when the index is 1 you are deleting the item from 3 items array which index is 1 and that is the second item out of 3, the first item is intact.
As a solution you can add the third argument to the splice, in order to have the same length array, which will solve the problem. Decide yourself what is best for your specific case, 3rd argument can be anything null,'undefined' or an object object.splice(index, 1, {}).
By the way, index-- doesn't do anything, index is set on every iteration.

Javascript: Find douplicated values from array with keys

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.

Separating key value pairs into two variables with for loop

edit: don't do this. this was a stupid way of doing something I tried when I was new to programming
I have a list of 32 pieces of data in an array that are paired like this
"foo:bar","baz:example","cat:dog"
and I want to loop through that array to and stop on the pair that matches the user's input. So, for example, if the user types in "foo" it'll return both "foo" and "bar" separately, and if the user types in "bar" it'll return both "foo" and "bar". There are no values that repeat.
Right now what I have is a huge table with if statements. So if the user's input is x, then it returns the correct value. I had to do the matching by hand, and I'm assuming that looping through the array until the correct value is found would be more efficient than 64 different ifs.
I've tried something like this (just an example) using two separate arrays:
for (var i=0;i<array.length;i++) {
if (array[i] === user_input) {
var index = indexOf(array[i]);
break;
}
}
and then using the index variable as the index number of the value in each array, but it returns undefined
I've also tried this: Separate key and value pairs into two arrays
But it gives me all the values in the array, which I don't want. I just want one specific value that the user inputs. And while I can select one specific portion of the array using the index number, I can't figure out how to make that dynamic (e.g. changing based on what the user inputs).
Is it even possible to do this? And if not, what would be the best way?
Thanks.
You can do this:
function getPair(arr, search) {
var rtn = arr.filter(function (v, i) {
return new RegExp("\\b" + search + "\\b").test(v);
})[0];
return rtn ? rtn.split(':') : -1;
}
Use it like this:
var array = ["foo:bar","baz:example","cat:dog"];
getPair(array, "foo"); // ["foo","bar"]
Note: The above function returns -1 if the search string isn't found in the array.
Here's a function that iterates over the array, and checks if the user_input is anywhere. If so, it will return the string that it found a match for.
function getPair(array, user_input) {
for (var i=0;i<array.length;i++) {
var pair = array[i].split(':');
if (pair.indexOf(user_input) >= 0) {
return pair;
}
}
return [];
}
var array = ["foo:bar","baz:example","cat:dog"];
getPair(array, "foo"); //will return ['foo', 'bar']
getPair(array, "bar"); //will return ['foo', 'bar']
getPair(array, "dog"); //will return ['cat', 'dog']
getPair(array, "zzz"); //will return []
I would suggest to work with objects. First, convert your array:
var pair,obj1={},obj2={};
for (var i=0;i<array.length;i++) {
pair=array[i].split(":");
obj1[pair[0]]=pair[1];
obj2[pair[1]]=pair[0];
}
This will give you the following objects:
obj1={
"foo":"bar",
"baz":"example",
"cat":"dog"
};
obj2={
"bar":"foo",
"example":"baz",
"dog":"cat"
};
Then based on the user input:
if (obj1[user_input]) {return [user_input,obj1[user_input]];}
else if (obj2[user_input]) {return [obj2[user_input],user_input];}
else return undefined;
Live demo: http://jsfiddle.net/x23qG/

Query if string is in any one of a set of arrays

I have a function written in JQuery. I have some arrays, like so:
var array1 = ["pink","yellow","green","red"],
array2 = ["peony","violet","rose","daisy"],
array3 = ["dalmation","kelpie","shepard","dachshund"],
I have a value from an input, called
$query
I would like to find out if the value of $query is equal to the value of any of the elements of any of the 3 arrays. If yes, I would like to know which array it is. An index number (ie 0 for array1, 1 for array2) would work fine.
This JSFiddle here http://jsfiddle.net/hJrAA/ from this StackOverflow question Search multiple arrays for a string and then set a var - jQuery is tantalising, but no matter what I change the value of the input query to,
console.log(inArrays('red', first, second, third));
(where 'red' is the query) it always returns the same value (2).
Can anyone suggest a way to modify that code so that it returns a reference to the specific array that the query was found in?
If you just wanted to return the index of the first array that was found I would do this:
function inArrays(val) {
var arrays = Array.prototype.slice.call(arguments, 1);
var idx = -1;
var i = 0;
while (i < arrays.length) {
if ($.inArray(val, arrays[i]) > -1) {
return i; // Breaks out of the loop as soon as a match is found
}
i++;
}
return idx;
}
Two things are different here from your fiddle
$.inArray is returning an index, not True or False, so if it's found the index will be >= 0. If an index is not found it will be -1.
I do a return i instead of setting the index and continuing. This not only breaks out of the loop earlier, it will return the index of the first match. Your original code always will return the last match.
http://api.jquery.com/jQuery.inArray/
The $.inArray() method is similar to JavaScript's native .indexOf()
method in that it returns -1 when it doesn't find a match. If the
first element within the array matches value, $.inArray() returns 0.
Because JavaScript treats 0 as loosely equal to false (i.e. 0 ==
false, but 0 !== false), if we're checking for the presence of value
within array, we need to check if it's not equal to (or greater than)
-1.
if ($.inArray(val, arrays[i]) > -1)

Categories

Resources