Searching JavaScript JSON objects - javascript

My PHP is returning the following JSON (2 entries shown, it could be more, but the structure will be the same):
{
"0": {
"campaign_id": "31",
"title": "new title",
"description": "new description",
"destinations": {}
},
"1": {
"campaign_id": "32",
"title": "title",
"description": "description",
"destinations": {}
}
}
I want to access the destinations where campaign_id matches a given value. How do I do that?

Using lodash.find:
var data = ...
var destinations = _.find(data, e => e.campaign_id == 31).destinations;
Pure JS
function find(data, predicate, def) {
for (var key in data) {
if (data.hasOwnProperty(key) && predicate(data[key], key)) {
return data[key];
}
}
return def;
}
var data = ...
var destinations = find(data, e => e.campaign_id== 31).destinations;
The best solution with dictionaries
In this case it would be the best if the server would actually send an object, where the items themselves are keyed by their campaign_id, then it would be just:
var data = ...
data[31].destinations

You can use Object.keys and the filter to perform matching:
Object.keys() returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop.
Array.prototype.filter() creates a new array with all elements that pass the test implemented by the provided function.
Array.prototype.map() creates a new array with the results of calling a provided function on every element in this array.
var obj = {...}; //your data object
var destinations = Object.keys(obj).filter(function(key) {
return obj[key].campaign_id === "32"
}).map(function(key) {
return obj[key].destinations;
});

Transform your response to object:
var obj = JSON.parse(response);
Now you can loop through the JSON:
var destinations;
for (var key in obj) {
if (obj[key].campaign_id == "value") {
destinations = obj[key].destinations;
break;
}
}
console.log(destinations);

Related

Adding empty key, value pair to javascript object

How can I add empty (key,value) pair to an existing object.
suppose I have an object as
var map = {
"name": "x"
};
How can I get below output
var map = {
"name": "x",
"": ""
};
I am looking for similar to push function in case of array.
You just need to use the [] operator, like that :
var map = {
"name": "x"
};
map[""] = "";

Compare key values within object for duplicate

I have an object:
myObj = {
attendent-0-id:"123",
attendent-0-name:"Bob Smith",
attendent-1-id:"1234",
attendent-1-name:"Alex Smith",
attendent-2-id:"123",
attendent-2-name:"Charlie Smith",
attendent-maxGuest:1,
attendent-party-name:"",
}
I need to create a loop that go through myObj and find all the id's and then compares them for duplicates. So in this case it would log an error because attendent-0-id is equal to attendent-2-id.
If I do find duplicates I need to set a flag to true;
I have tried a bunch of things and am just stuck at this point. Thanks for any help.
In your case you can go through myObj using Object.keys() via:
for (const key of Object.keys(obj))
use a plain object as a map to store the previous values of the ids:
const map = {};
use a regex pattern to make sure only the specific ids are evaluated:
const pattern = /^attendent-\d+-id$/;
and then with the help of the map, log the error on duplicate ids:
if (value in map) {
console.error(`${map[value]} is equal to ${key}, which is ${value}`);
}
Example:
const myObj = {
'attendent-0-id': "123",
'attendent-0-name': "Bob Smith",
'attendent-1-id': "1234",
'attendent-1-name': "Alex Smith",
'attendent-2-id': "123",
'attendent-2-name': "Charlie Smith",
'attendent-maxGuest': 1,
'attendent-party-name': "",
};
function errorOnDuplicateIds(obj) {
const map = {};
const pattern = /^attendent-\d+-id$/;
for (const key of Object.keys(obj)) {
if (pattern.test(key)) {
const value = obj[key]
if (value in map) {
console.error(`${map[value]} is equal to ${key}, which is ${value}`);
} else {
map[value] = key
}
}
}
}
errorOnDuplicateIds(myObj);
const ids = []; // keep track of found ids
Object.keys(myObj).forEach(key => { // iterate over all properties of myObj
// check if property name is in format "attendent-" *some number* "-id"
if (/^attendent-\d+-id$/.test(key)) {
// check if the id has already been found
if (ids.findIndex(id => id === myObj[key]) !== -1) {
console.log('error');
} else {
ids.push(myObj[key]);
}
}
});
You can use Object.entries and a Map (keyed by value) for this:
var myObj = {"attendent-0-id":"123","attendent-0-name":"Bob Smith","attendent-1-id":"1234","attendent-1-name":"Alex Smith","attendent-2-id":"123","attendent-2-name":"Charlie Smith","attendent-maxGuest":1, "attendent-party-name":""};
var dupes = [...Object.entries(myObj).reduce(
(map, [key,val]) => map.set(val, (map.get(val) || []).concat(key)),
new Map
).values()].filter(keys => keys.length > 1);
console.log(dupes);
This solution does not give any particular meaning to the format of the keys.
Having said that, your object structure looks suspicious of bad design: you should not have enumerations in your object keys. For that you should use arrays.
Object.values(myObj) will create an array of all values and then you can use any way to find duplicate elements in that array.
var myValues = Object.values(myObj); //This will create an array of all values
var uniq = myValues.map((val) => {
return {count: 1, val: val}
}).reduce((a, b) => {
a[b.val] = (a[b.val] || 0) + b.count
return a
}, {});
var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)
if (duplicates.length) {
return true;
} else {
return false;
}
My first advice would be to redefine your object to something more flexible.
let myObject = {
attendants : [
{
id: "123",
name: "Bob Smith"
},
{
id: "456",
name: "Alex Smith"
},
{
id: "768",
name: "Charlie Smith"
},
],
maxGuest: 1,
partyName: ""
};
This will allow you to iterate the attendants.
for (var attendant in myObject.attendants){
doSomething(attendant.id, attendant.name);
}
You can also sort the attendant:
// Sort by id
myObject.attendants.sort(function(left, right){
return left.value - right.value;
});
// Sort by name
myObject.attendants.sort(function (left, right){
var leftName = left.name.toLowerCase();
var rightName = right.name.toLowerCase();
if (leftName < rightName) return -1;
if (leftName > rightName) return 1;
return 0;
});
Now, lets assume you don't have a choice. Then it gets complicated.
You need to create (or modify an existent) a sort algorithm so it can use keys that are generated as:
myObject[`attendent-${index}-id`]
myObject[`attendent-${index}-name`]
and keep the pair

What's the difference between this two javascript objects

I am trying to get values from the following object. The for loop works in one of the objects but won't in the other javascript object. I was wondering what the difference and how can I get it to work in the other object?
Object 1:
var objects = [
{
"foo" : "bar",
"bar" : "sit"
},
{
"foo" : "lorem",
"bar" : "ipsum"
}
];
Object 2:
{
"4dd5a49e366": {
"name" : "bar",
"bar" : "sit",
"date": "2016-08-03T04:48:04.283Z"
},
"519c5056af2": {
"name" : "lorem",
"bar" : "ipsum",
"date": "2016-09-03T04:48:04.283Z"
}
}
I want to do a search for items where name attribute is matching some search_term. And return the items.
Here is the search for loops am using.
function searchFor(toSearch) {
var results = [];
toSearch = trimString(toSearch); // trim it
for(var i=0; i<objects.length; i++) {
for(var i in objects[i]) {
if(objects[i][key].indexOf(toSearch)!=-1) {
if(!itemExists(results, objects[i])) results.push(objects[i]);
}
}
}
return results;
}
console.log(searchFor('o'));
This works for the first object and not for the second. How can I get it to work for the second?
The first variable is an array of objects. Since it is an array you can use all array methods on it.
Second one is an object with keys 4dd5a49e366 & 519c5056af2 which in turn are again object and have few properties.
You cannot use array methods on this second object
how can I get it to work in the other object?
Hope this snippet will be useful
var myObject = {
"4dd5a49e366": {
"name": "bar",
"bar": "sit",
"date": "2016-08-03T04:48:04.283Z"
},
"519c5056af2": {
"name": "lorem",
"bar": "ipsum",
"date": "2016-09-03T04:48:04.283Z"
}
}
// a function to accept the name value
function findByName(name) {
var thisObject = "";
for (var keys in myObject) { // looping over objects
var getThisObject = myObject[keys];
if (getThisObject.name === name) { // Checking if name matches
thisObject = myObject[keys]; // assigning the object to a variable
}
}
return thisObject // return that variable
}
var getMyObject = findByName('bar');
console.log(getMyObject)
JSFIDDLE
EDIT
if I enter just findByName('b'); it should return results that the
full name
You need to use indexOf to find if this name value contains the specific character.
Use an array to store all the relevant object where the name value contains this specific character.Return that array from the function.
function findByName(name) {
var thisObject = [];
for (var keys in myObject) {
var getThisObject = myObject[keys];
if (getThisObject.name.indexOf(name)!==-1) {
thisObject.push(myObject[keys]);
}
}
return thisObject
}
var getMyObject = findByName('b');
JSFIDDLE 2
I suggest you do some reading on JavaScript Object literals and Arrays. The first example is an array of objects. The second is just an object. Two completely different data structures.

merge two object and rename same property

I have two object which contain some similar properties. I want to merge those two object in one object and also want to rename the similar properties from both objects.
var selectedEntity = {"UsageS":"123","DateS":"2016","IsEstimeated":"True"};
var ComapareEntity = {"UsageC":"124","DateC":"2015","IsEstimeated":"False"}
Result = {"UsageS":"123","DateS":"2016","IsEstimeatedS":"True","UsageC":"124","DateC":"2015","IsEstimeatedC":"False"};
Please suggest some solution using lodash.
Try to put these two objects in a json array, so that index can used to name duplicate keys
var selectedEntity = {
"UsageS": "123",
"DateS": "2016",
"IsEstimeated": "True"
};
var ComapareEntity = {
"UsageC": "124",
"DateC": "2015",
"IsEstimeated": "False"
}
var toLoopArray = [selectedEntity, ComapareEntity]
var resultantObject = {};
toLoopArray.forEach(function(item, index) {
for (var keys in item) {
if (!(resultantObject.hasOwnProperty(keys))) {
resultantObject[keys] = item[keys]
} else {
resultantObject[keys + index] = item[keys]
}
}
})
console.log(resultantObject)
JSFIDDLE

javascript: How to get highest layer of json object as array?

With an array of objects in a form like this:
[
{
1429={
{
8766={...},
8483={...},
7345={...}
}
}
},
{
9041={...}
}
]
how could i get back an array like this?:
[1429, 9041]
If the array of objects would be in another structure this code would work:
var obj = {
"5": "some",
"8": "thing"
};
var keys = $.map(obj, function (value, key) {
return key;
});
console.log(keys);
That would return [5, 8]. But in my example it just would return the indexes [0,1]
Even if I wouldn't know the depth of the object - is it possible to get the values on that level? I dont need the indexes, I need those values. I couldn't find anything about it so far. Any tips for me maybe?
P.S.: I know that i could work out something with these keys and a loop, but I'm just asking for a simplier way to do it.
Regards
you are looking for the keys in a json object, you can get them this way:
Object.keys(obj);
for the object example:
var obj = {
"5": "some",
"8": "thing"
};
you will get:
["5","8"]
for an array of object of this type:
var arrayObject = [{},{},{}];
you can use a map and get the keys:
var keys = arrayObject.map(function(k){
return Object.keys(k);
});
keys is an array of arrays of keys. Example, for the following object (similar to your data structure):
var l= [
{
1429:{
8766: "test",
8483:"test",
7345: "test"
}
},
{
9041: "test"
}
];
you will get:
[["1429"],["9041"]]
apply concat and you will get what you are looking for. Here how to apply concat in the case of multiple arrays.
var arrayOfKeys = [].concat.apply([], keys);
now you will get:
["1429","9041"];
In your specific case you could use
var keys = [];
root.forEach(function(v) { keys = keys.concat(Object.keys(v)); });
If instead you have a tree of arrays and you want the keys of all other objects instead (but not recursing into objects) then a simple recursive function would do it:
function topKeys(x) {
if (x && x.constructor === Array) {
var result = [];
x.forEach(function(item) {
result = result.concat(topKeys(item));
});
return result;
} else if (typeof x === "object") {
return Object.keys(x);
} else {
return [];
}
}

Categories