I need to push a hash into array only if it doesn't contain the hash that i want to add.
For example i have an array of hashes :
var someArray = [
{field_1 : "someValue_1", field_2 : "someValue_2"},
{field_1 : "someValue_3", field_2 : "someValue_4"},
{field_1 : "someValue_5", field_2 : "someValue_6"}
]
The value
{field_1 : "someValue_1", field_2 : "someValue_2"}
should not be pushed into array as it is already there, but the value
{field_1 : "someValue_7", field_2 : "someValue_8"}
should, as the array does't contain such value.
Is there any way to do it using jQuery?
Now i'm just using $.each loop and check if the array contains some hash. If it does i trigger a flag. But i don't like this solution.
create custom prototype to check the presence of object in the array. Please check the prototype design below.
Array.prototype.contains=function(x){
for(i in this){
if((x.field_1==this[i].field_1)&&(x.field_2==this[i].field_2))
return true;
}
return false;
}
Using above prototype, you can check if object present in an array.
var someArray = [
{field_1 : "someValue_1", field_2 : "someValue_2"},
{field_1 : "someValue_3", field_2 : "someValue_4"},
{field_1 : "someValue_5", field_2 : "someValue_6"}
];
var a1={field_1 : "someValue_1", field_2 : "someValue_2"};
var a2={field_1 : "someValue_7", field_2 : "someValue_8"};
if(!someArray.contains(a1)) someArray.push(obj); // it will NOT BE pushed
if(!someArray.contains(a2)) someArray.push(obj); // it will be pushed
Alternatively, you can augment Array or define your prototype as the following :
Array.prototype.add = function(element){
var itemExists = false;
for(var i=0;i<this.length;i++){
if(this[i]==element){
itemExists = true;
break;
}
}
if(itemExists==false)
return this.push(element);
}
So, using [].add(yourElement) will only add that element to your array if it doesn't already exist. Feel free to change the structure of the argument and if condition according to your needs.
I have faced this issue a lot of times, and what I always do is to write a function that returns true if the element is already in given set of elements.
function IsElementInSet(Element,Set)
{
var ElementIsInSet=false;
for(var i=0;i<Set.length;i++)
{
if(Set.field_1==Element.field_1&&Set.field_2==Element.field_2)
{
ElementIsInSet=true;
break;
}
}
return ElementIsInSet;
}
This is how I do the things. Create function that do some checks and give me true if the element is already there.
There are other possible solutions to optimise the search if you are working with big arrays and feel the things working slow, but I doubt you will.
EDIT: Also, about using parallel structure for saving current values - you can find it very tricky to have ordinary array (one dimension) in which only one value is saved - in your case it will be Element.field_1+Element.field_2 (concatenate the strings). Then you can write other function that check if there is given value in this array. I think the two solution are the same and it is question about style, not speed.
Related
I have an array that looks something like this.
Users : {
0 : { BidderBadge: "somestuff", Bidders: 6, }
1 : { BidderBadge: "somemorestuff", Bidders: 7,}
}
I want to search the array using lodash to find a value inside of each of the user objects.
Specifically, I want to use values from another similar array of objects to find the value.
var bidArray = [];
_.each(this.vue.AllUsers, function(user) {
_.each(this.vue.Bids, function(bid) {
if(user.BidderBadge == bid.Badge) {
bidArray.push(user);
}
});
});
This is what I have and it works, but I want to do it using only one loop instead of two. I want to use something like _.indexOf. Is that possible?
If you want to avoid nesting, you just have to modify Azamantes' solution a bit
var bidders = this.vue.Bids.reduce(function(acc, bid) {
return acc[bid.BidderBadge] = true;
}, {});
var bidArray = this.vue.AllBidders.filter(function(bidder) {
return !!bidders[bidder.Badge];
});
It is difficult to give an accurate answer with an example that doesn't coincide with the input that your provide.
Anyway, supposing your data structures were more or less like this ones, you could solve the problem with lodash _.intersectionWith.
Intersect both arrays using a comparator that checks the correct object properties. Also, take into account that users must go first in the intersection due to the fact that you're interested in its values.
function comparator(user, bid) {
return user.BidderBadge === bid.Badge;
}
console.log(_.intersectionWith(users, bids, comparator));
Here's the fiddle.
I wrote this code and it`s simple , i have an empty object which will contain some other objects as properties , but the object stays empty and don`t add the needed properties ..
let buildProfileClientValidator = function(form , rules){
let elements = {};
function init(){
//Some code that works fine
addElement(elementName , elementType);
addElement(elementName , elementType);
//the elements object should now have some other objects as properties
//but it`s empty !!!!
console.log(elements);
}
function addElement(elementName , elementType){
//this condition works fine
if( !elementExist(elementName) ){
//console.log(elementName , elementType); also works fine -> the values of elementName , elementType are present
elements[elementName] = {
type : elementType,
value : '',
rules : (rules[elementName] == undefined) ? '' : rules[elementName].split('|')
};
}
}
}
so what i`m missing ?!
After examining your code, but not knowing how buildProfileClientValidator gets called (and specifically what the rules parameter is), I can trace the problem to this line:
(rules[elementName] === undefined) ? '' : rules[elementName].split('|')
I have modified your code (to make it testable) in the following fiddle (https://jsfiddle.net/hssbsL19/40/) and when I replace that line with a static value, the code works.
I want to change the key of JSON attribute and keep/persist its position/Index.
E.g.
{"Test1" : {
mytest1:34,
mytest2:56,
mytest6:58,
mytest5:89,
}
}
Now I want to change the key mytest6 to mytest4 and keep its position as it is.
Note: In my case I can't use Array.
Thanks.
jsonObj = {"Test1" : {
mytest1:34,
mytest2:56,
mytest6:58,
mytest5:89,
}
};
var old_key = "mytest6";
var new_key = "mytest4";
if (old_key !== new_key) {
Object.defineProperty(jsonObj.Test1, new_key,
Object.getOwnPropertyDescriptor(jsonObj.Test1, old_key));
delete jsonObj.Test1[old_key];
}
console.log(jsonObj);
This method ensures that the renamed property behaves identically to the original one.
Also, it seems to me that the possibility to wrap this into a function/method and put it into Object.prototype is irrelevant regarding your question.
Fiddle
I want to do something relatively simple, I think anyways.
I need to compare the pathname of page with an object's kv pairs. For example:
if("pathname" === "key"){return value;}
That's pretty much it. I'm not sure how to do it in either regular Javascript or jQuery. Either are acceptable.
You can see my fiddle here: http://jsfiddle.net/lz430/2rhds1x3/
JavaScript:
var pageID = "/electrical-electronic-tape/c/864";
var pageList = [{
"/electrical-electronic-tape/c/864": "ElectronicTape",
"/industrial-tape/c/889": "IndustrialTape",
"/sandblasting-tape/c/900": "SandblastingTape",
"/Foam-Tape/c/875": "FoamTape",
"/double-coated-d-c-dhesive-tape/c/872": "DCTape",
"/Adhesive-Transfer-Tape/c/919": "ATTape",
"/Reflective-Tape/c/884": "ReflectiveTape",
"/custom-moulding": "CustomMoulding",
"/request-a-quote": "RequestQuote"
}];
var label = pageID in pageList;
$('.el').html(label);
First, your "pageList" should just be a plain object, not an object in an array:
var pageList = {
"/electrical-electronic-tape/c/864": "ElectronicTape",
"/industrial-tape/c/889": "IndustrialTape",
"/sandblasting-tape/c/900": "SandblastingTape",
"/Foam-Tape/c/875": "FoamTape",
"/double-coated-d-c-dhesive-tape/c/872": "DCTape",
"/Adhesive-Transfer-Tape/c/919": "ATTape",
"/Reflective-Tape/c/884": "ReflectiveTape",
"/custom-moulding": "CustomMoulding",
"/request-a-quote": "RequestQuote"
};
Then you can set "label" to the value from the mapping:
var label = pageList[pageID] || "(not found)";
That last bit of the statement above will set the label to "(not found)" if the lookup fails, which may or may not be applicable to your situation.
It depends kinda on the logic you want to implement. If you want to say "if object has the key, then do X, and if not, then do Y", then you handle that differently than "set label to the object's key's value if the key is there, or else set it to undefined or something else".
For the first case you do:
if (pageList.hasOwnProperty(pageID) ) {
label = pageList[pageID];
}
else {
// do whatever, maybe some error?
}
For the second case, you can just say
var label = pageList[pageID] || 'notFound';
As indicated by #Pointy, either get rid of the array or subsiture pageList[0] for pageList and pageList[0][pageID] for pageList[pageID] above, if you need to keep the array.
The following problem is driving me crazy.
_.each(collection, function( account, key ){
var totalPhy = that.physicianCollection.where({ 'Hospital_Id__c' : account.Id }).length;
account.physicians = { 'total' : totalPhy };
});
It is working when Hospital_Id__c same as account.Id. But my account Id is a sub string of the hospital_Id__c. How do I search and get the count? I tried index of and search methods. Pls suggest. Thanks in advance.
_.where is a simple use case of _.filter to match exact properties. In your case you will need to actually use _.filter and write the logic yourself. I'm not sure what the account id / hospital id look like, but the code will probably look something like :
var totalPhy = that.physicianCollection.filter(function(phys, index, collection){
//phys is your model
return phys.get('Hospital_Id__c').indexOf(account.Id) != -1;
//(or however the ids are set, your logic here)
}).length;
account.physicians = { 'total' : totalPhy };
http://underscorejs.org/#filter