Here is the scenario:
There is a parameter titledlistOfSelectedProductIdsthat contains
all of the selected ids.
There is another list titled listOfAllPossibleProducts, which
contains a list of objects. That object contains a ProductId,
ProductName, and ProductCode. It looks something like this:
The task at hand:
I need to loop through my listOfSelectedProductIds. If the ProductId matches a ProductId from listOfAllPossibleProducts, then I need to return that object.
Here is what I am doing:
function SelectedProducts(listOfSelectedProductIds){
for (var index = 0; index < listOfSelectedProductIds.length; index++) {
var currentItem = listOfSelectedProductIds[index];
var desiredProduct = _.contains(listOfAllPossibleProducts, currentItem);
if (desiredProduct === true) {
return listOfAllPossibleProducts[index];
}
}
}
What's currently happening:
My loop is getting the selected id as expected i.e. currentItem, but _.contains(...)
always returns false.
Question:
What is the best way to find the objects in
listOfAllPossibleProducts that have ProductIds that match my
ProductIds in the listOfSelectedProductIds
How about using _.filter:
var result = _.filter(listOfAllPossibleProducts, function (el) {
return _.contains(listOfSelectedProductIds, el.id);
});
Or the non-underscore method:
var result = listOfAllPossibleProducts.filter(function (el) {
return listOfSelectedProductIds.indexOf(el.id) > -1;
});
DEMO
create another structure productsByProductId once!
var productsByProductId = {};
listOfAllPossibleProducts.forEach(p => {
productsByProductId[p.ProductId()] = p
});
and maybe a helper function
function getProductById(id){
return productsByProductId[id];
}
and use this to map the ids to the nodes
var selectedProducts = listOfSelectedProductIds.map(getProductById)
Related
function buildEVQuestionLists(category) {
var items = [];
var mySurvey = SurveyUtil.Surveys.Get(CurrentPID());
var remoteQuestions = mySurvey.Questions;
for (var i = 0; i < remoteQuestions.Count; i++) {
var question = remoteQuestions[i];
if (question.IsInCategory(category)) items.push(question.Id);
}
return items;
}
This is what return items gives:[EV10013,EV10361,EV10022,EV10009,EV10003,EV10025,EV10020,EV10017,EV10005,EV10000,EV10043,PH10040,PH10013]
Now I would like to go through this list and only return the items that start with 'EV'.
As you tagged startswith, instead of filtering the array afterwards, you could add an extra check if the string starts with EV before pushing the question id to the items array.
For example
if (question.IsInCategory(category) && question.Id.startsWith("EV")) items.push(question.Id);
I am trying to merge an object into an array. Based on the title of the object, if it already exists in the array I want to add the amount of the object into the existing amount.
For example:
let items = [{"title":"x","amount":1}, {"title":"y","amount":1}, {"title":"z","amount":1}];
let obj1 = {"title":"x","amount":2};
If obj1 is merged into items the expected output would be
[{"title":"x","amount":3}, {"title":"y","amount":1}, {"title":"z","amount":1}]
Here is the solution I've come up with so far, Its working but I feel like there has to be a more elegant solution out there.
mergeResponses(x){
var found = this.items.some(function (arr) {
return arr.title === x.title;
});
if(!found){
//item doesnt exist, add to array
this.items.push(x);
}else{
//item already exists, add amount to existing amount
let dupItem = this.items.find(function (y) {
return y.title == x.title;
});
dupItem.amount += x.amount;
}
}
Below is a direct translation of your requirements. It's slightly more elegant than your implementation in the sense that the lookup only needs to be performed once.
let items = [{"title":"x","amount":1}, {"title":"y","amount":1}, {"title":"z","amount":1}];
let item = {"title":"x","amount":2};
let existing = items.find(i => i.title === item.title);
if (existing) {
existing.amount += item.amount;
} else {
items.push(item);
}
console.log(items);
you can do like this also,I don't say that this the better way but this also one way to do this.
var xyz=items.find(function(item){
if(item.title==obj1.title)
return item;
});
if(xyz)
xyz.amount+=obj1.amount;
else
items.push(obj1);
you can do as :
var items = [{"title":"x","amount":1}, {"title":"y","amount":1}, {"title":"z","amount":1}];
var obj = {"title":"x","amount":3};
matches = _.filter(items, i => i.title === obj.title)
if (matches) {
_.forEach (
matches,
match => match.amount += obj.amount
)
} else {
items.push(obj)
}
console.log(JSON.stringify(items))
I hava a problem with copy a objects to array. I think it is an problem with reference.
In my program i have few array. First is dataForMonth - it is array of objects with data for month. And second is an products array which contains products objects. Product have property forecastArry wchich is array of objects.
Here code :
this.allProducts.map(function (product) {
var dataForMonth = data.filter(function (e) {
return e.dataId === product.productDataId;
});
var z = { posId: product.sales_plan_pos_id, arry: [] }
for (var sheetMonth of sheet.channels) {
var result = dataForMonth.filter(function (e) {
return e.CHANNEL === sheetMonth.CHANNEL;
});
product.forecastArry[someId].channels = result;
);
The problem is that the every changed channels property have the same value - its a value from last product?
Anybody know how to fix it ?
Seems like you want to edit each product in this.allProducts. So you want to add a return value to your map. You should also use let so that the scope of variables declared is preserved within map function, although I believe the map function already takes care of that. In addition, not that you have to reassign this.allProducts to your map function call. So your answer should be something like the following:
this.allProducts = this.allProducts.map(function (product) {
let dataForMonth = data.filter(function (e) {
return e.dataId === product.productDataId;
});
let channelsForMont = [];
let z = { posId: product.sales_plan_pos_id, arry: [] }
for (let sheetMonth of sheet.channels) {
let result = dataForMonth.filter(function (e) {
return e.CHANNEL === sheetMonth.CHANNEL;
});
product.forecastArry[someId].channels = channelsForMont;
return product;
);
P.S Your original code has some missing brackets and result variable is unused. You should do something about them.
I have some JSON data that I am retrieving from https://status.mojang.com/check and am storing in a variable. I'm still quite new to JSON/JS and I can't seem to find any answers on google.
Code:
function checkMojang() {
var mojangStatus = mojang.status();
mojangStatus.then(function (message) {
var response = JSON.parse(message);
})
}
Data I am using can be seen at the link above. I am trying to check all the data in the json array, see if any of the values contain "yellow" or "red" and get the keys for those values along with their checked value but can't figure out how to do so.
You can loop through the array and then through the object properties and make a new object using the colors as keys
var response = [{"minecraft.net":"green"},{"session.minecraft.net":"red"},{"account.mojang.com":"green"},{"auth.mojang.com":"green"},{"skins.minecraft.net":"green"},{"authserver.mojang.com":"yellow"},{"sessionserver.mojang.com":"green"},{"api.mojang.com":"green"},{"textures.minecraft.net":"green"},{"mojang.com":"red"}];
var new_response = {};
response.forEach(function(obj){
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
if(new_response[obj[prop]] == undefined) new_response[obj[prop]] = [];
new_response[obj[prop]].push(prop);
}
}
})
console.log(new_response);
The you can use the object for your needs as
new_response["red"]
giving you the list of all key with red value.
you can use the method array.foreach() to execute a provided function once per array element and the for ... in to itarate over the enumarable properties.
So you can test the value and get keys for the value "yellow" or "red"
response.forEach(function(element) {
for (k in element) {
if (element[k]=="red" or element[k]=="yellow") {
// k is the key
}
}
});
function checkMojang() {
var mojangStatus = mojang.status();
mojangStatus.then(function (message) {
var response = JSON.parse(message);
for (i = 0; i < response.length; i++) { // iterate over response array
var item = response[i]; // get item from array
var key = Object.keys(item)[0]; // get the key of the item
var value = item[key]; // get the value of the item
if (value === 'yellow' || value === 'red') {
// do something, like adding it to a list
}
}
});
}
How can I search in this object/array for the first elements to get the field name?
In this example I need to get second if I am searching for #999999
colors = {
first: ['#cccccc', '#999999'],
second: ['#999999', '#626262'],
third: ['#eeeeee', '#afafaf']
};
I tried something like this:
for(var field in colors) {
if(colors.hasOwnProperty(field)) {
if(colors[field] === '#999999') {
console.log(field); // gives 'second'
var color1 = colors[field][0],
color2 = colors[field][1];
}
}
}
Maybe this could get more simplified.
Try using Object.keys() , Array.prototype.filter() ; return property name of object where "#999999" is at index 0 of array
var colors = {
first: ['#cccccc', '#999999'],
second: ['#999999', '#626262'],
third: ['#eeeeee', '#afafaf']
};
var n = "#999999";
var res = Object.keys(colors).filter(function(key, index) {
return colors[key][0] === n
});
console.log(res[0])
colors[field] is the entire Array. You forgot to test against the Array element. Your loop should look more like:
for(var field in colors){
if(colors[field][0] === '#999999'){
console.log(field); // gives 'second'
}
}
If you want to find all the key names with that search parameter in that array position, use an array to capture them. Here's a generic function to solve that just in case you have more than one array with that param in that position.
function find(obj, param, pos) {
var out = [];
for (var p in obj) {
if (obj[p][pos] === param) out.push(p);
}
return out;
}
find(colors, '#999999', 0); // ['second']
find(colors, '#999999', 1); // ['first']
DEMO