I have an array that looks like this:
var myArray = [
{'id' : 1, 'name' : 'test1'},
{'id' : 2, 'name' : 'test2'},
{'id' : 3, 'name' : 'test3'}
];
Then I have a variable that contains some id:
var someId = 2;
How can I check if myArray contains an Object, who's id is equal to someId?
You can use the .some() method:
var isThere = myArray.some(function(element) {
return element.id == someId;
});
The .some() method returns a boolean true if the callback returns true for some element. The iteration stops as soon as that happens.
If you want the element in the array and not just a yes/no answer, you can pass the same kind of callback to .find():
var theElement = myArray.find(function(element) {
return element.id == someId;
});
When that callback returns true, the iteration stops and .find() returns the element itself. If none is found, it returns undefined.
You can try following
var filteredArray = myArray.filter(function(item) {
return item.id == someId
});
if(filteredArray.length > 0) {
console.log("Found");
}
Vanilla JS:
var myArray = [
{'id' : 1, 'name' : 'test1'},
{'id' : 2, 'name' : 'test2'},
{'id' : 3, 'name' : 'test3'}
];
function findby(arr, key, val){
for(var i=0; i<arr.length; i++){
if(arr[i][key] === val){
return arr[i];
}
}
return null;
}
var found = findby(myArray, "id", 2);
alert(found.name);
Related
I have an array which looks like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
},
]
}
]
I want to remove duplicate itemP so with a function it will look like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : null
},
]
}
]
When I try I always have errors. It is possible to do this?
Update
I try to do this :
console.log(array.map(pack =>
pack.values.map((item) => {
var test = JSON.stringify(item)
var set = new Set(test)
return Array.from(set).map((item)=> JSON.parse(item))
}
)
))
Unexpected end of JSON input
I also try something will filter but it doesn't work:
console.log(this.package.map(pack => pack.values.filter(
(value, index , array) => array.itemP.indexOf(value) === index
)))
Instead of mapping every key property, I suggest cloning the whole structure and setting the object value as null in the cloned one, avoiding unintentionally mutating the original structure.
function nullifyDupes(array) {
const clone = JSON.parse(JSON.stringify(array));
const seen = {};
clone.forEach(pack => {
pack.values.forEach(items => {
for (const item in items) {
const id = items[item].id;
if (seen[id]) items[item] = null;
else seen[id] = true;
}
});
});
return clone;
}
const originalArray = [{
key : { id : 1 , pack : "pack 1"},
values : [{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}]
}];
const mutatedArray = nullifyDupes(originalArray);
console.log(mutatedArray);
To achieve expected result, use below option of using map
Loop array using map
Use nameArr to check duplicate and assigning null value
Loop values array and check the name in nameArr using indexOf and assign null
var array = [
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
}
]
console.log(array.map(v => {
let nameArr = []
v.values = v.values.map(val => {
if(nameArr.indexOf(val.itemP.name) !== -1){
val.itemP.name = null
}else{
nameArr.push(val.itemP.name)
}
return val
})
return v
}))
You can use map and an object to check if its already exist. Like
var obj = {}
and loop over values
var values = [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
values.map((v) => {
if(!obj[v.itemP.id + '-' + v.itemP.name]) {
obj[v.itemP.id + '-' + v.itemP.name] = true;
return v;
}
return { item : v.item }
})
You can map your array elements to array objects which don't include your duplicates using .map(). For each iteration of .map() you can again use .map() for your inner values array to convert it into an array of objects such that the duplicates are converted to null. Here I have kept a seen object which keeps track of the properties seen and their stringified values. By looping over all the properties in your object (using for...of), you can work out whether or not the key-value pair has been seen before by using the seen object.
The advantage of this approach is that it doesn't just work with one property (ie not just itemP), but it will work with any other duplicating key-value pairs.
See example below:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
const seen = {};
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
for (let p in vobj) {
vobj[p] = seen[p] === JSON.stringify(vobj[p]) ? null : vobj[p];
seen[p] = seen[p] || JSON.stringify(vobj[p]);
}
return vobj;
});
return obj;
});
console.log(res);
For an approach which just removed itemP from all object in accross your array you can use:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
let itemP = "";
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
vobj.itemP = itemP ? null : vobj.itemP;
if('itemP' in vobj) {
itemP = itemP || JSON.stringify(vobj.itemP);
}
return vobj;
});
return obj;
});
console.log(res);
i have an object like this in my console:
ObjectName1 : Array(3)
0 : { id : 1, name : 'foo' },
1 : { id : 2, name : 'foo-2' },
2 : { id : 3, name : 'foo-3' },
ObjectName2 : Array(3)
0 : { id : 1, foo : 'bar' },
1 : { id : 2, foo-2 : 'bar-2' },
2 : { id : 3, foo-3 : 'bar-3' },
and as usually if we want to get the name, just write : ObjectName1[key].name right ?
now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
i have written like this :
// just say there is an each above this comment
var name = ObjectName1[key].name;
var bar = ObjectName2[key]+"."+name;
// end each
but it just showed
[Object object].foo
[Object object].foo-2
[Object object].foo-3
the output should be like this :
bar
bar-2
bar-3
it is possible doing like i want to do ? help me please if it is possible
any help will be very appreciated.
*note : i'm not sure what is the case name in my problem, so forgive me if the title went wrong
thanks
Try this one. Loop through each object in ObjectName1 object and get the name in appropriate index, this name will be the key for the ObjectName2 object. Then use that key to print the appropriate value from ObjectName2
var ObjectName1 = [{'id' : 1, 'name' : 'foo'}, {'id' : 2, 'name' : 'foo-2'}, {'id' : 3, 'name' : 'foo-3'}];
var ObjectName2 = [{'id' : 1, 'foo' : 'bar'}, {'id' : 2, 'foo-2' : 'bar-2'}, {'id' : 3, 'foo-3' : 'bar-3'}];
for(var i = 0; i < ObjectName2.length; i++){
console.log(ObjectName2[i][ObjectName1[i]['name']]);
}
Something like this?
var name = ObjectName1[key].name;
ObjectName2.forEach(function(a) {
if (a.keys().includes(name)) {
var bar = a[name];
// then do what you want with bar
}
}
As commented, your key is an object. Hence, it is showing [Object object].foo-3.
You will have to use 2 loops and check if the key is inside current object. If yes, print it, else continue.
var ObjectName1 =[
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' },
]
var ObjectName2 = [
{ id : 1, foo : 'bar' },
{ id : 2, 'foo-2' : 'bar-2' },
{ id : 3, 'foo-3' : 'bar-3' },
];
ObjectName1.forEach(function(obj){
ObjectName2.forEach(function(obj2){
var key = obj.name;
if(key in obj2){
console.log(obj2[key])
}
})
})
now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
If you know those are parallel arrays (where [0] in one array is intentionally a match for [0] in the other array), you can simply loop through:
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
That assumes you know they're parallel arrays.
If not, you have to search for it. Array.prototype.findIndex will return the index of the first element where a callback returns true:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
If you don't really need the key (e.g., index) of the matching object in ObjectName2, just the object, use find instead:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 7 years ago.
I've got an object which looks like this:
var myObject = {
array1: [
{id: "aaa"},
{id: "bbb"},
{id: 'ccc'}
],
array2: [
{id: "ddd"},
{id: "eee"},
{id: 'fff'}
],
childObject: {
property: "value"
}
};
What I need is a function that gets the name of an array with certain id value. For example:
getArrayName("myObject", "id", "eee") //returns "array2"
because it's always "id" it can be simplified to:
getArrayName("myObject", "ccc") //returns "array1"
I'm using lodash in this project, so I've tried .findKey(), but I can't get it to work.
Try this
function getArrayName(myObject, value)
{
for ( var arrayId in myObject)
{
var arr = global[ arrayId ];
for ( var counter = 0; counter < arr.length; counter++)
{
if ( arr[ counter ].id == value )
{
return arrayId ;
}
}
}
return "";
}
You can do this and also generalise the parameters you want to search by:
function getArrayName(objName, propKey, propVal) {
var obj = window[objName];
var resArray = _.find(obj, function (arr) {
return _.some(arr, function (arrObj) {
return arrObj[propKey] === propVal;
});
})
var index = 0;
for (var key in obj) {
if (obj[key] === resArray) {
index = key;
break;
}
}
return index;
}
getArrayName("myObject", "id", "ccc") //returns "array1"
Fiddle
Try this:
<script>
var myObject = {
array1: [
{id: "aaa"},
{id: "bbb"},
{id: 'ccc'}
],
array2: [
{id: "ddd"},
{id: "eee"},
{id: 'fff'}
],
childObject: {
property: "value"
}
};
function getArrayName(obj,id){
$.each(obj,function(key,value){
$.each(obj[key],function(key1,val){
if(val.id === id)
alert(JSON.stringify(obj[key]));
})
});
}
getArrayName(myObject,'eee');
</script>
I'm trying to get a recursion work in JavaScript. This is my code.
var getCategory = null;
getCategory = function (id, cats) {
if (!cats || !cats.length) return null;
for (var i = 0; i < cats.length; i++) {
var cat = cats[i];
if (cat && cat.Id == id) {
return cat;
}
else if (cat && cat.Children && cat.Children.length) {
return getCategory(id, cat.Children);
}
}
return null;
}
This code basically searches in the hierarchy of data for a specific element of a specific id.
Let's say that my sample data is:
var sampleData = [
{Id : 1, Children : [{Id:11, Children:[]}, {Id : 12, Children : []}]},
{Id : 2, Children : [{Id:21, Children:[]}, {Id : 22, Children : []}, {Id : 23, Children : []}]},
{Id : 3, Children : [{Id:31, Children:[]}, {Id : 32, Children : []}, {Id : 33, Children : []}]}
]
The problem is that when I call this function like:
getCategoriy(21, sampleData); //it gives null
even when get:
getCategiry(11, sampleData); //gives perfect object back
What am I doing wrong?
You're starting to loop through the cats, but if you see an entry that has children, you're recursing into that entry and then terminating your loop. That means you don't see any of the cats after that entry.
Instead of
return getCategory(id, cat.Children);
You need to call it and only return if it returns !null:
value = getCategory(id, cat.Children);
if (value) {
return value;
}
I have my data object:
var elements = {
'element' : {
'name' : 'test',
'price' : '55'
},
'element' : {
'name' : 'letev',
'price': '223'
}
};
Now, I don't know how can I find each element by name for example.
I need to find element by name test, and then acces it's other parameters (price,..)
You must change elements to array:
var elements = [
{
'name' : 'test',
'price' : '55'
},
{
'name' : 'letev',
'price': '223'
}
];
function findElementByName(name, elementsForSearch) {
if (name) {
elementsForSearch.filter(function(elem){
return elem.name === 'name';
});
return elementsForSearch[0];
}
return {};
}
alert(findElementByName('test', elements).name)
Assuming your object was an array instead of the syntax you used:
var elements = [
{
'name' : 'test',
'price' : '55'
},{
'name' : 'letev',
'price': '223'
}
];
You can filter the element out like this:
searchName = 'test';
elements.filter(function(element){
return element.name == searchName;
});
This will only return the elements that have 'test' as name.
Or as a function:
function filterByName(array, namr){
array.filter(function(element){
return element.name == name;
});
}
Called like this:
array result = filterByName(elements, 'test');
In case you need to support IE 8 or lower, you can use a polyfill for Array.prototype.filter.
you can do that if your elements object was an array, i.e.
var elements = [{
'element' : {
'name' : 'test',
'price' : '55'
},
'element' : {
'name' : 'letev',
'price': '223'
}
}];
var price;
for (var i=0; i <elements.length; i++) {
if (elements[i].name === 'test') {
price = elements[i].price;
break;
}
}
Try with:
var elements = [
{
'name' : 'test',
'price' : '55'
},
{
'name' : 'letev',
'price': '223'
}
];
var search = 'letev';
for (var i = 0; i < elements.length; i++) {
if (elements[i].name == search) {
alert('found!');
break;
}
}
Or using Array.filter:
var search = 'letev';
var output = elements.filter(function(element) {
return element.name == search;
});
Try this
var List= (JObject)JsonConvert.DeserializeObject(jsonstring);
var result= List["element"].Children().Select(node => node["name"]== "Test").ToList();