Find similar items in an object - javascript

I have an object that looks like so:
{
title: "test",
subtitle: "test",
"list-item-1": "This is item 1",
"list-item-2": "This is item 2",
"list-item-3": "This is item 3"
}
I want to find all keys in that object that end with a -1, or any -numerical value. And then group all of those together in some way that I can access them by calling something like "if an item has a -1 at the end of it, find all other items that have the same first part (list-item in this case) and save them to their own array or variable.
How would I go about this?

one simple way to harvest properties is to use built in methods like keys(), filter(), and test():
var obj={
title: "test",
subtitle: "test",
"list-item-1": "This is item 1",
"list-item-2": "This is item 2",
"list-item-3": "This is item 3",
};
var arrOK=Object.keys(obj).filter(/./.test, /list-item-\d+$/);
alert(arrOK); // shows: "list-item-1,list-item-2,list-item-3"

First of all, it isn't an array - that is a Javascript Object, however it is malformed in that there are not commas between items.
You can iterate through the object like so, and access the name of each object property as below.
for (item in obj) {
if (obj.hasOwnProperty(item)) {
// the 'item' variable is the name you are looking for.
// use a regex pattern to match on -#.
}
}

You can use for..in to iterate over the object keys and then just do some simple string/regex matching.
var new_obj = {};
// iterate over keys in object
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
// ends in "dash number"
if (key.match(/-\d+$/)) {
// get new key by stripping off "dash number"
var newkey = key.replace(/-\d+$/, "");
// ensure new object has this property; make it an array
if (!new_obj.hasOwnProperty(newkey)) {
new_obj[newkey] = [];
}
// append original object item to this new property
new_obj.push(obj[key]);
}
}
}

Related

Retrieving data from an object from an array of objects

I have a list of objects like this.
I'm stuck right now, couldn't figure out how to retrieve a value of a an object, by submitting the key
"ListOfObjects": [
{
"SomethingToRetrieve": "This Is The First Value"
},
{
"AnotherThingToRetrieve": "This Is Another Value "
},
{
"LastToRetrieve": "This Is the Last Value"
}
]
I want by creating a function :
retrieveValue(Key){
// by giving as Example AnotherThingToRetrieve
// It will return the Value of this key
//return "This Is Another Value "
}
You could filter all objects that have that key and then return the value from the first matching object. If you leave off the [0] at the end you'll get an array of all matching values.
var listOfObjects = [
{
"SomethingToRetrieve": "This Is The First Value"
},
{
"AnotherThingToRetrieve": "This Is Another Value "
},
{
"LastToRetrieve": "This Is the Last Value"
}
]
const retrieveValue = key => listOfObjects.filter(x => x[key]).map(x => x[key])[0];
console.log(retrieveValue("AnotherThingToRetrieve"))
Use forEach over your json. Object.keys(e) will give you keys inside object literals.
Loop through JSON
Loop through all keys within Object literal {}
Match with key return value if matched.
var ListOfObjects= [{"SomethingToRetrieve": "This Is The First Value"},{"AnotherThingToRetrieve": "This Is Another Value "},{
"LastToRetrieve": "This Is the Last Value"}]
function getVal(key){
ListOfObjects.forEach(function(e){//step #1
Object.keys(e).forEach(function(eachKey){//step #2
if(key == eachKey){//step #3
console.log(e[key]);
return ;
}
})
})
// one liner using find
alert(Object.values(ListOfObjects.find(el=>Object.keys(el).find(ee=>ee==key))))
}
getVal('AnotherThingToRetrieve');
You can also use find The find() method returns the value of the first element in the provided array that satisfies the provided testing function.Inside commented statement under alert.
You have a nested array. You can run a nested for loop to iterate through it until you find a match like so:
var listOfObjects = [
{
"SomethingToRetrieve": "This Is The First Value"
},
{
"AnotherThingToRetrieve": "This Is Another Value "
},
{
"LastToRetrieve": "This Is the Last Value"
}
]
var key = "LastToRetrieve";
console.log(retrieveValue(key));
function retrieveValue(Key){
// by giving as Example AnotherThingToRetrieve
// It will return the Value of this key
//return "This Is Another Value "
var value = "";
for(var obj in listOfObjects) {
for(var item in listOfObjects[obj]) {
if(item === key) {
value = listOfObjects[obj][item];
break;
}
}
}
return value;
}

Correctly reorganising JSON to JS array

I have a JSON string that is similar to below:
[
{"id":"112233","region":"UK","city":"London","name":"Company 1"},
{"id":"112244","region":"UK","city":"London","name":"Company 2"},
{"id":"112255","region":"UK","city":"Manchester","name":"Company 3"},
{"id":"112266","region":"UK","city":"Manchester","name":"Company 4"}
]
I am trying to rebuild this into a JS array like this:
[
{
["London"]: [
["112233"] : [{"id":"112233","region":"UK","city":"London","name":"Company 1"}],
["11224"] : [{"id":"112244","region":"UK","city":"London","name":"Company 2"}],
],
["Manchester"]: [
["112255"] : [{"id":"112255","region":"UK","city":"Manchester","name":"Company 3"}],
["112266"] : [{"id":"112266","region":"UK","city":"Manchester","name":"Company 4"}]
]
}
]
Here is the code I am using to do this:
var company = [];
var companies = [];
var cities = [];
// generate citites
for (var i = 0; i < dump.length; i++)
{
// check if city exits
if(!cities.includes(dump[i].city.trim())) {
cities[dump[i].city.trim()] = companies;
}
}
// add companies
for (var i = 0; i < dump.length; i++)
{
company['company_name'] = dump[i].company_name;
company['region'] = dump[i].region;
cities[dump[i].city][dump[i].id] = company;
}
console.log(cities);
Now I get an error stating Cannot set property '112233' of undefined TypeError: Cannot set property '112233' of undefined.
Can someone explain what I'm doing wrong?
The formatting of your desired results is a little strange because you are using [] for what looks like objects with keys. I'm assuming that's a typos and that you really want an object.
Here's a quick easy way to do that with reduce():
let dump = [
{"id":"112233","region":"UK","city":"London","name":"Company 1"},
{"id":"112244","region":"UK","city":"London","name":"Company 2"},
{"id":"112255","region":"UK","city":"Manchester","name":"Company 3"},
{"id":"112266","region":"UK","city":"Manchester","name":"Company 4"}
]
let obj = dump.reduce((obj, item) => {
let city = obj[item.city] || (obj[item.city] = {}) // add city obj to object if not there.
city[item.id] = item // add item.id to city obj
return obj
}, {})
console.log(obj)
EDIT:
The way reduce() works is to start with a value that is passed in the second parameter, here that's an empty object {} that is called obj in the callback, and then iterate through the array (dump). With each iteration we look and see if this obj has a property with the name of the current item in the iteration. If not add it and assign a new object {}. Then with that object in hand, add a property corresponding to item.id and adding the whole item to it.
You could write the entire thing as a for loop, but reduce is pretty succinct — it just takes a while to get used to it.

Iterate through object values - javascript

Given this data structure:
{ "name": [ "can't be blank" ], "league_id": [ "You already have a team in this league." ] }
How can I print this?
Can't be blank
You already have a team in this league
So basically I want to iterate through the values of the object. How can I do this with Javascript? Thank You!
Your data structure doesn't make much practical sense in that your property values are arrays with just one element in them. While legal, for the data you are showing, it makes more sense just to have the strings as the values.
Either way, a for/in loop over the object will allow you to iterate the keys.
With current structure:
let obj = {
"name": ["can't be blank"],
"league_id": ["You already have a team in this league."]
};
for(var key in obj){
console.log(obj[key][0]); // Here, you have to index the property value, which is an array
}
With arrays removed:
let obj = {
"name": "can't be blank",
"league_id": "You already have a team in this league."
};
for(var key in obj){
console.log(obj[key]); // Here, you can access the key value directly
}
You can also use Object.keys(obj), along with a .forEach() method call, which is a newer technique:
let obj = {
"name": ["can't be blank"],
"league_id": ["You already have a team in this league."]
};
Object.keys(obj).forEach(function(key){
console.log(obj[key][0]); // Here, you have to index the property value, which is an array
});
Let's see:
const obj = { "name": [ "can't be blank" ], "league_id": [ "You already have a team in this league." ] }
console.log(Object.values(obj).map(value => value.toString()).join("\n"))
Get values of the keys in object with Object.values method
map over them
Since the value itself is Array, cast it to string (or get the first element)
Join them with a new line

How to get unique objects from objects array in javascript

I have an array of objects that looks like the image below. Is there a way by which I can have an array that contains unique objects with respect to id ? We can see below that the id are same at index [0] and index [2].
Is there a way that I can get an array containing objects with unique id and the first object from the last index is added to the unique array rather than the first object. In this case, Object at index[2] should be added instead of object at index[0]:
To get an array of "unique" objects(with last index within the list) for your particular case use the following approach (Array.forEach, Array.map and Object.keys functions):
// exemplary array of objects (id 'WAew111' occurs twice)
var arr = [{id: 'WAew111', text: "first"}, {id: 'WAew222', text: "b"}, {id: 'WAew111', text: "last"}, {id: 'WAew33', text: "c"}],
obj = {}, new_arr = [];
// in the end the last unique object will be considered
arr.forEach(function(v){
obj[v['id']] = v;
});
new_arr = Object.keys(obj).map(function(id) { return obj[id]; });
console.log(JSON.stringify(new_arr, 0, 4));
The output:
[
{
"id": "WAew111",
"text": "last"
},
{
"id": "WAew222",
"text": "b"
},
{
"id": "WAew33",
"text": "c"
}
]
The best way to do this is to modify your data structure into an object itself where each key is one of the IDs:
{
"WadWA7WA6WAaWAdWA...": {
"text": "birla"
},
"WadWA...": {
"test": "ab"
}
}
and so forth. If the data comes from a source formatted that way, you can always map the array of results to this format.
You could create a hash using the id as the key and keeping the value as the entire object:
var myHash = new Object();
var i;
for(i = 0; i < yourArray.length; i++) {
var yourObjId = yourArray[i][id];
myHash[yourObjId] = yourArray[i];
}
You would be left with a hash myHash containing objects with unique id's (and only the last object of duplicates would be stored)
Try this: just add to a new object using id as the key
var arr = [{id:'123', text: 'a'}, {id:'234', text: 'b'}, {id:'123', text: 'c'}];
var map = new Object();
for(var i in arr){ map[arr[i].id] = arr[i]; }
var newArr = [];
for(var i in map){ newArr.push(map[i]); }
newArr shall contain the 2nd and 3rd object.

How do I find all occurences of a given property in a list of objects where the property is in depth n?

The Issue: Given a list of objects(model) and a path(eg: "organization.LongName") I wish to find all values that match this path and push them to an array.
This is a plnkr with this issue : Plnkr
And an illustration showing an example object and the values I am interested in
*EDIT: Looking at these answers it would appear that I have been unclear in my explanation. The point here is that
the path is a variable and passed as a string. like : "x.y.z...n"
I dont know its depths in advance and as such I need to be able to find the property regardless of the depth of the property.
OK, my answer is a bit off the wall, and also introduces a library dependency, but if you want something a bit more flexible rather than straight-up loops and code, you may want to consider JSONPath which allows you to interact with JavaScript objects/arrays as you would XPath, only with a little different syntax.
Given the model in your plnkr example, the following will give you the list you desire:
jsonPath(model,'$..organization..LongName');
// $ = the root element
// .. = descend until whatever comes next (either organization or LongName)
// organization|LongName = the object you're looking for
The result snippet is:
["Group A", "Group B", "Group A", "Group B", "Group A", "Group B", "Group A", "Group B", "Group C", "Group D"...]
Using modern browsers you can use the Array.map() function.
var obj = {
id: 0,
organization:[
{id:0, LongName:"group A"},
{id:1, LongName:"group B"}
],
number: 123,
LongName: "John World"
};
var groupLabels = obj.organization.map(function(e){
return e.LongName;
});
console.log(groupLabels);
JS Fiddle
If your stuck somewhere that insists on using outdated browsers you can shim the map() function in using the code provided in the compatibility section within the above MDN link.
consider this solution
function getOccurences(jsonObject, path) {
path = '$..' + path.replace('.','..');
return jsonPath(jsonObject, path);
}
you can call it this way:
getOccurences(someJsonData, 'organization.LongName')
you can try this this works perfect.
function getValuesFromArray(obj, property)
{
// obj = your object in which you want to find your property
// property == your property which you want to find
for(var index=0; index<obj.length; index++)
{
if(obj[index] instanceof Object)
getValuesFromObject(obj[index], property);
else if(obj[value] instanceof Object)
getValuesFromObject(obj[value], property);
}
}
function getValuesFromObject(obj, property)
{
// obj = your object in which you want to find your property
// property == your property which you want to find
for(value in obj)
{
if(value == property)
myArray.push(obj[property]);
else if(obj[value] instanceof Array)
getValuesFromArray(obj[value], property);
else if(obj[value] instanceof Object)
getValuesFromObject(obj[value], property);
}
}

Categories