I have an empty array called result[]. A user then clicks a link which calls a function called getId() that passes the clicked id to check if it matches the id in another array called productsArray[].
Jackets
var productsArray = [
{id:0, title:"Product A",description:"description 0"},
{id:0, title:"Product B",description:"description 1"},
{id:2, title:"Product C",description:"description 2",},
{id:0, title:"Product D",description:"description 3",},
{id:4, title:"Product A",description:"description 4",},
{id:5, title:"Product A",description:"description 5",}
],
result = [];
If the user clicks the Jackets link (which has an id of 0) the 3 items in the productsArray, will get returned: Product A, B and D.
The code I have to achieve this actually works:
var output;
var container;
for(key in productsArray) {
if (productsArray[key].id == id) {
result.push(productsArray[key].title, productsArray[key].description);
}
}
container = document.getElementById('content');
output=result;
container.innerHTML=output;
<div id="content"></div>
But the problem is that ALL the data is assigned to the result[] key index:
For example:
[0]Produduct A title
[1]Product B title
[2]Product C title
What I would like to achieve a way of splitting up the data along the lines of the following:
output+= result[0].title + result[0].description
Any help appreciated.
Cheers
You could map the result and the wanted keys of the product.
function getId(id) {
document.getElementById('content').innerHTML = productsArray
.filter(function (product) {
return product.id == id;
})
.map(function (product) {
return ['title', 'description']
.map(function (key) { return product[key]; })
.join(' ');
})
.join('<br>');
}
var productsArray = [{ id: 0, title: "Product A", description: "description 0" }, { id: 0, title: "Product B", description: "description 1" }, { id: 2, title: "Product C", description: "description 2" }, { id: 0, title: "Product D", description: "description 3" }, { id: 4, title: "Product A", description: "description 4" }, { id: 5, title: "Product A", description: "description 5" }];
Jackets
<div id="content"></div>
You have to assign a variable that takes value of title and description and then push that value to array. like below code
function getId(id){
var output;
var container;
for(key in productsArray) {
if (productsArray[key].id == id) {
newObj= "" ; // assign to blank
newObj = productsArray[key].title +" "+ productsArray[key].description; //assign as per you need the format
result.push(newObj); // push it to array
}
}
container = document.getElementById('content');
output=result;
container.innerHTML=output;}
Related
In my application I create a JavaScript object based on a JSON similar to this:
{
name: "root",
id: 112,
children: [
{
name: "child one",
id: 231,
children: [
{name: "grand child 1", id: 334, children: []},
{name: "grand child 2", id: 784, children: []}
]
},
{
name: "child two",
id: 343,
children: []
}
]
}
How can I remove any Child by his id? Please note that I don’t know the static path to the node e.g id == 334 so I am wondering how I could remove that node with just knowing it's id.
function del(obj,id){
obj.children = obj.children.filter(el => {
if(el.children) del(el,id);//delete subnodes
return el.id !== id; //delete this
});
}
A recursive approach to traverse the objects, usable as:
del(
{ children:[ { id:1 }, { id:2, children:[{id:1}] }] },
1
);
check this :
var abc = your json object;
//now filter the item based on id
abc = jQuery.grep(
abc.children,
function (item,index) {
return item.id != "343";
});
hope it helps.
var delIt = function (obj,id) {
return obj.children = obj.children.filter(function (child) {
if(child.children) delIt(child,id);
return child.id!=id;
});
}
var x= delIt(Tobj,335);
You can use filter function to collect items which are not equals to given id
I'm using At.js plugin. It's working fine for a single object (demo)
var names1 = ["Jacob", "Isabella", "Ethan", "Emma", "Daniel", "Madison"];
var names = $.map(names1, function(value, i) {
return {
'id': i,
'name': value,
'email': value + '#yahoo.com'
};
});
But when I try to add multiple objects it's not working (demo). I knew the code is the problem.
I want to display the description when a user selects the name of the person using # tag.
$(function() {
$.fn.atwho.debug = true
var names1 = [{
"name": "Jacob",
"description": "description one description one description one"
},
{
"name": "Isabella",
"description": "description two description two description two"
}
];
var names = $.map(names1, function(value, description, i) {
return {
'id': i,
'name': value,
'email': description
};
});
var at_config = {
at: "#",
data: names,
headerTpl: '<div class="atwho-header">Service List <small>↑ ↓ </small></div>',
insertTpl: '${email}',
displayTpl: "<li>${name}</li>",
limit: 200
}
$inputor = $('#inputor').atwho(at_config);
$inputor.caret('pos', 47);
$inputor.focus().atwho('run');
});
The map function in Jquery does not take each element in a object as the function argument, you get the entire object (the element in the list) and you then need to extract the name, and the description. You were almost there.
$(function() {
$.fn.atwho.debug = true
var names1 = [{
"name": "Jacob",
"description": "description one description one description one"
},
{
"name": "Isabella",
"description": "description two description two description two"
}
];
var names = $.map(names1, function(value, index) { //Here I have only used value
return {
'id': index,
'name': value.name, //Here I take value.name from the object
'email': value.description //And value.description from the object
};
});
var at_config = {
at: "#",
data: names,
headerTpl: '<div class="atwho-header">Service List <small>↑ ↓ </small></div>',
insertTpl: '${email}',
displayTpl: "<li>${name}</li>",
limit: 200
}
$inputor = $('#inputor').atwho(at_config);
$inputor.caret('pos', 47);
$inputor.focus().atwho('run');
});
In my application I create a JavaScript object based on a JSON similar to this:
{
name: "root",
id: 112,
children: [
{
name: "child one",
id: 231,
children: [
{name: "grand child 1", id: 334, children: []},
{name: "grand child 2", id: 784, children: []}
]
},
{
name: "child two",
id: 343,
children: []
}
]
}
How can I remove any Child by his id? Please note that I don’t know the static path to the node e.g id == 334 so I am wondering how I could remove that node with just knowing it's id.
function del(obj,id){
obj.children = obj.children.filter(el => {
if(el.children) del(el,id);//delete subnodes
return el.id !== id; //delete this
});
}
A recursive approach to traverse the objects, usable as:
del(
{ children:[ { id:1 }, { id:2, children:[{id:1}] }] },
1
);
check this :
var abc = your json object;
//now filter the item based on id
abc = jQuery.grep(
abc.children,
function (item,index) {
return item.id != "343";
});
hope it helps.
var delIt = function (obj,id) {
return obj.children = obj.children.filter(function (child) {
if(child.children) delIt(child,id);
return child.id!=id;
});
}
var x= delIt(Tobj,335);
You can use filter function to collect items which are not equals to given id
i have 2 object/arrays:
var objA = {
Red Chair : "DC10291",
USBDongle : "USKI82322",
}
var arrayB = [
{
field: "Yellow Banana",
id: "Yellow Banana"
},
{
field: "Red Chair",
id: "Red Chair"
},
{
field: "Garden",
id: "Garden"
}
]
What i am trying to do is, that if a KEY from objA, e.g. Red Chair, is present in arrayB, then remove it from arrayB.
I have done this:
var arrayClone = _.cloneDeep(arrayB);
var removeThese = [];
Object.keys(arrayClone).forEach(function(p) {
removeThese.push(p)
});
removeThese.forEach(function(remove) {
arrayB.forEach(function(item) {
if(item.id === remove) {
delete objA[remove];
}
});
});
The above works as expected, however is this the most effieicnt? Reasone i ask is because looping throuhg and array within an array loop doesnt feel the best practice? And will have performance impact
You can simply filter it, like this
_.filter(arrayB, obj => !objA.hasOwnProperty(obj.field))
// [ { field: 'Yellow Banana', id: 'Yellow Banana' },
// { field: 'Garden', id: 'Garden' } ]
This uses ES2015's Arrow function syntax. You can write the same with a normal function like this
arrayB.filter(function(obj) {
return !objA.hasOwnProperty(obj.field);
});
// [ { field: 'Yellow Banana', id: 'Yellow Banana' },
// { field: 'Garden', id: 'Garden' } ]
We are basically filtering out all the objects whose field value is a key in objA.
If you would like to keep the original arrayB and get a reduced version of it according to your condition then Array.prototype.reduce() does that with O(n) time complexity. However if you would like to perform this operation in place then Array.prototype.reduceRight() does that with O(n) time complexity.
var objA = {
"Red Chair" : "DC10291",
"USBDongle" : "USKI82322",
},
arrayB = [
{
field: "Yellow Banana",
id: "Yellow Banana"
},
{
field: "Red Chair",
id: "Red Chair"
},
{
field: "Garden",
id: "Garden"
}
],
arrayC = arrayB.reduce((p,c) => !objA[c.field] ? p.concat(c) : p, []);
console.log(arrayC);
arrayB.reduceRight((p,c,i,a) => (p[c.field] && a.splice(i,1),p),objA);
console.log(arrayB);
I came up with the following way to reduce my data:
data = [{ id: 99991, name: "NoData1", title: "No Data" },
{ id: 99992, name: "NoData2", title: "No Data" },
{ id: 99993, name: "NoData3", title: "No Data" }];
var dataMapName = data.reduce((rv, v) => {
rv[v.name] = v;
return rv;
}, {}) : null
Now If I want to access the id I can enter the following:
var NoData1Id = dataMapName['NoData1'].id
or
var NoData1Id = dataMapName.NoData1.id
However some of my data has spaces in the name such as:
data = [{ id: 99991, name: "NoData1", title: "No Data" },
{ id: 99992, name: "NoData2", title: "No Data" },
{ id: 99993, name: "NoData3", title: "No Data" },
{ id: 99994, name: "NoData 4", title: "No Data" },
];
Is there a way that I could change my function so that it first removed spaces from the name during the reduction so that I could still enter:
var NoData4Id = dataMapName.NoData4.id
You can use regex to remove all spaces from name.
\s will match all the space characters like tabs, spaces, etc. g flag is for matching all the spaces.
rv[v.name.replace(/\s/g, '')] = v;
Demo
Well, then just replace space with an empty string.
var dataMapName = data.reduce((rv, v) => {
rv[v.name.replace(' ', '')] = v;
return rv;
}, {}) : null
and other option is to use the data as is, just make sure to use bracket notation.
var NoData4Id = dataMapName.["NoData 4"].id
You can change key of the map while you are inserting:
data = [{ id: 99991, name: "NoData1", title: "No Data" },
{ id: 99992, name: "NoData 2", title: "No Data" },
{ id: 99993, name: "NoData3", title: "No Data" }];
var dataMapName = data.reduce((rv, v) => {
var vName = v.name.replace(/\s/g,'');
rv[vName] = v;
return rv;
}, {}) : null