Assuming that I have a JS object wich contains other objects inside it, but all of them have the same structure.
I am trying to search inside them for any duplicated values.
For example:
{
{
id: "123"
name: "John"
surname: "Smith"
phone: "123456789"
},
{
id: "456"
name: "Jack"
surname: "Jones"
phone: "9876789123"
},
{
id: "789"
name: "John"
surname: "Doe"
phone: "123456789"
}
}
I want to search and find that the property 'phone' with value '123456789' is the same on both objects with ids '123' and '789'.
Note: the property/value combination that I am searching for is unknown beforehand.
First, if the outer structure is a plain Object, use an Array instead. If you can't change the structure, I'd convert it first.
DEMO: http://jsfiddle.net/3Y2qr/
if (!Array.isArray(data))
data = Object.keys(data)
.sort(function(a,b) { return a - b })
.map(function(key) { return data[key] })
Then you can reduce the set to groups of matches.
var groupByPhone = data.reduce(function(found, obj) {
if (found[obj.phone])
found[obj.phone].push(obj)
else
found[obj.phone] = [obj]
return found
}, {});
var dupes = Object.keys(groupByPhone)
.filter(function(key) {
return groupByPhone[key].length > 1
})
So now groupByPhone is an object where the keys are the unique phone numbers, and the values are the objects that have that number.
The dupes will be a list of phone number keys that can be used to lookup groups of duplicate objects in groupByPhone.
Array.prototype.filter to the rescue !
var searchFor = '123456789';
var filteredResult = arrayOfObjects.filter(function( obj ) {
return obj.phone === searchFor;
});
console.log( filteredResult );
Related
I have a object which has some properties for one user, and I have array of objects which is returned from API.
My goal is to check which object of Array of objects has the same property as the one single initial object, and then it should return only part of it's properities.
I have tried to use .map on Array of objects but it seems not workig.
Below is the code example. I have also prepared codesandbox if You wish.
const user =
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
car: "audi"
}
;
const usersAnimal = [
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
animal: "cat",
animalSize: "small",
animalName: "Bat"
},
{
name: "john",
lastName: "smith",
fullName: "john smith",
animal: "dog",
animalSize: "middle",
animalName: "Jerry"
},
{
name: "Anna",
lastName: "Nilsson",
fullName: "Anna Nilsson",
animal: "cow",
animalSize: "big",
animalName: "Dorrie"
}
];
const filtered = usersAnimal.map((userAnimal)=>userAnimal.fullName === user.fullName && return userAnimal.animalName & userAnimal.animalSize & userAnimal.animal);
thanks
https://codesandbox.io/s/admiring-edison-qxff42?file=/src/App.js
For case like this, it would be far easier if you filter it out first then proceed using map:
const filtered = usersAnimal
.filter((animal) => animal.fullName === user.fullName)
.map(({ animalName, animalSize, animal }) => {
return {
animalName,
animalSize,
animal
};
});
I am providing a for loop solution as I haven't learnt many array methods in javascript.
For me the simplest option is to use a for loop and an if check to loop through the arrays values to check for included values.
for (let v in usersAnimal) {
if (usersAnimal[v].fullName === user.fullName) {
console.log(usersAnimal[v])
}
}
The code above will log the entire usersAnimal object containing the fullname we are looking for.
{
name: 'jan',
lastName: 'kowalski',
fullName: 'jan kowalski',
animal: 'cat',
animalSize: 'small',
animalName: 'Bat'
}
commented for further understanding
for (let v in usersAnimal) {
//loops though the array
if (usersAnimal[v].fullName === user.fullName) {
//when the index value 'v' has a fullname that matches the user fullname value
// it passes the if check and logs that object value
return console.log(usersAnimal[v])
//return true...
}
//return null
}
//etc
If you want to filter, I recommend you to use filter.
The map method will create a new array, the content of which is the set of results returned by each element of the original array after the callback function is operated
const user = {name:"jan",lastName:"kowalski",fullName:"jan kowalski",car:"audi"};
const usersAnimal = [{name:"jan",lastName:"kowalski",fullName:"jan kowalski",animal:"cat",animalSize:"small",animalName:"Bat"},{name:"john",lastName:"smith",fullName:"john smith",animal:"dog",animalSize:"middle",animalName:"Jerry"}];
// Get an array of matching objects
let filtered =
usersAnimal.filter(o => o.fullName === user.fullName);
// You get the filtered array, then you can get the required properties
filtered.forEach(o => {
console.log(
'animal:%s, animalSize:%s, animalName:%s',
o?.animal, o?.animalSize, o?.animalName
);
});
// Then use map to process each element
filtered = filtered.map(o => {
const {animal, animalSize, animalName} = o;
return {animal, animalSize, animalName};
});
console.log('filtered', filtered);
I have an array of objects, that contains properties that are objects:
let allPersons = [
{ id: "abcdefg",
name: "tom",
...
phone: {
brand: "blah"
id: "hijklm"
...
}
},
{ id: ....}, {...}, {...}
];
What I need to do is filter those objects and returning all the phones, filtering them by id so all phones returned are unique.
I tried to retrieve first all the phones:
// allPersons is the full array mentioned above
let phones = [...new Set(allPersons.map(person => person.phone))];
then I tried to return all the unique phones, but unsuccessfully:
let result = phones.map(phone => phone.id).filter((value, index, self) => self.indexOf(value) === index)
This returns only the unique ids of the phones, but I want the entire object. What can I do?
UPDATE:
phone Ids are NOT unique, e.g. nokia3310 has id 1, nokia3330 has id 2, etc: so tom and john can have the same phone and phone ids could be duplicated!
Make an object indexed by IDs instead, then take the object's values:
const phonesById = Object.fromEntries(
allPersons.map(
({ phone }) => [phone.id, phone]
)
);
const uniquePhones = Object.values(phonesById);
If you're trying to get the phone object in each object of the array, then the code below will do that for you.
It gets the phone object and stores it in a
var objArr = [
{id: "abcdefg", name: "tom", phone: {brand: "blah", id: "hijklm"}},
{id: "guidiuqwbd", name: "john", phone: {brand: "hihihih", id: "ayfva"}},
{id: "yuygeve", name: "doe", phone: {brand: "hahahah", id: "cqcqw"}}
]
var allPhoneObjects = [];
objArr.forEach(function(currObj){
var phoneObj = currObj.phone;
allPhoneObjects.push(phoneObj);
});
console.log(allPhoneObjects);
I propose you the following solution
let uniques = new Set();
const phones = allPersons.filter(({phone}) => (
uniques.has(phone.id) ? false : !!uniques.add(phone.id)
)).map(p => p.phone)
Basically, we define a Set to record ids of the phones already processed, and a filter function on the allPersons array, that returns only the phones not already in the Set. We complete with the map to extract only the portion of JSON needed
EDIT
You can use just one function on the allPersons array using the reduce function
let uniques = new Set();
const phones = allPersons.reduce( (filtered, {phone}) => {
if (!uniques.has(phone.id)) {
filtered.push(phone);
uniques.add(phone.id);
}
return filtered
}, [])
Is there an easy way to convert an object to name value pairs like jquery generates with .serializeArray()
This doesn't work:
var data = {
name: "John",
age: 26,
isMale: true,
occupation: null
}
var serialized = $(data).serailizeArray();
Is there an easy way to do this without looking at every property and converting them to name-value pairs?
I'm using a helper function that is written by someone else that adds a name value pair to each call before posting it to the server. Obviously it's not working if I give it a regular object or an array that has a regular object.
You can do this with a combination of Object.entries and map (assuming you want the data in the same format that serializeArray returns):
var data = {
name: "John",
age: 26,
isMale: true,
occupation: null
};
var result = Object.entries(data).map(([k, v]) => ({name: k, value: v}));
console.log(result);
This should do the trick if you're using ES6:
var data = {
name: "John",
age: 26,
isMale: true,
occupation: null
}
console.log(
Object.entries(data).map(([name, value]) => ({ name, value }))
)
// ES5:
console.log(
Object.keys(data).map(function (name) { return { name: name, value: data[name] } })
)
I want to create an object with an array property which looks like this:
var arrayOfUsers = {
id: "some user id",
username : "some names",
roles : [array with roles]
}
And i would like to access an element by id, something like, arrayOfUsers['some id']['roles'];
I am new to json. I've tried different ways, but always ended up with bunch of errors.
First, this is a JavaScript object. JSON is a string representation of JavaScript objects.
Second, it's important to know the difference between an object and an array. In general, consider Objects to be defined with curly braces { } and Arrays with braces [ ]
Values in Arrays are accessed by their index with the arr[index] syntax while objects use obj[key] syntax to access the value assigned to some key on the object.
For your scenario, I'd avoid using arrays, because you want to be able to access objects by key, not by index.
var users = {
"some user id": {
username : "some names",
roles : {
"some role id": {
name: "role name"
}
}
}
};
In reality, this isn't a very effective data structure, because you'd likely want to deal with arrays for looping, rendering, etc, but to answer your question about being able to index by the Id of user and role, this is how your data would have to be structured.
Here is how you declare:
var currentUser,
currentRole,
arrayOfUsers = {
id: 1,
username: "Sample Value",
roles: [{
roleId: 1,
name: "Admin"
},
{
roleId: 2,
name: "Cashier"
}]
};
This is how you access it:
for (var i = arrayOfUsers.length; i--;) {
currentUser = arrayOfUsers[i];
for (var x = currentUser.roles.length; x--;) {
currentRole = currentUser.roles[x];
console.log("ID=" + currentRole.id + "Name=" + currentRole.name);
}
}
First, you have to make difference between array which defined by [], and Objects, by {}.
If you want to make an array of JSON, you can do the following :
var arrayRoles = [{
idRole: 1,
type: 'admin'
}, {
idRole: 2,
type: 'user'
}];
var userArray = [{
id: 1,
username: 'toto',
roles: arrayRoles
}, {
id: 2,
username: 'titi',
roles: arrayRoles
}, {
id: 3,
username: 'toto',
roles: arrayRoles
}];
Then, if you want to iterate over all your data, you can do it by using forEach loop, which tends to be more elegant :
userArray.forEach(function(elm){
//Our roles array
var roles = elm.roles;
//For all item in roles array
roles.forEach(function(value){
//display type of role, for example.
console.log(value.type);
});
});
But if you want to search a specific item in your JSON array, you can use filter method, by using high order function.
function filterBy(key, filter){
return function(elm){
return elm[key] === filter;
}
}
Then, you can apply this function to your filter, by passing specific field and value, and it will return an array of results :
var filtered = userArray.filter(filterBy('username', 'toto'));
//Display '1'
console.log(filtered[0].id);
//Display '3'
console.log(filtered[1].id);
I have an object like this:
var person = {
name: "John",
surname: "Smith",
phone: "253 689 4555"
}
I want:
John,Smith,253 689 4555
Is there some easy way?
If possible, could you please provide an example where I can also define the separator?
You can use this one-liner in modern browsers
Object.keys(person).map(function(k){return person[k]}).join(",");
This code will be useful when you want to extract some property values from an array of objects as comma separated string.
var arrayObjects = [
{
property1: "A",
property2: "1"
},
{
property1: "B",
property2: "2"
},
{
property1: "C",
property2: "3"
}
];
Array.prototype.map.call(arrayObjects, function(item) { return item.property1; }).join(",");
Output - "A,B,C"
Here is a simpler one liner. It uses the Object.values() method instead of Object.keys
Object.values(obj).join(",");
try this:
var key,
person = {
name: "John",
surname: "Smith",
phone: "253 689 4555"
},
array = [];
for ( key in person ) {
if ( person.hasOwnProperty( key ) ) {
array.push( person[ key ] );
}
}
console.log( array.join( ',' ) );
or in function style:
var
getValues = function ( obj ) {
var key,
array = [];
for ( key in obj ) {
if ( obj .hasOwnProperty( key ) ) {
array.push( obj [ key ] );
}
}
return obj.join( ',' );
};
var person = {
name: "John",
surname: "Smith",
phone: "253 689 4555"
};
console.log( getValues( person ) );
Write a function like this:
function toCSV(obj, separator) {
var arr = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(obj[key]);
}
}
return arr.join(separator || ",");
}
And then you can call it like:
toCSV(person, "|"); // returns "John|Smith|253 689 4555"
or
toCSV(person); // returns "John,Smith,253 689 4555"
var arr = [
{
key_1: "A",
key_2: "1"
},
{
key_1: "B",
key_2: "2"
},
{
key_1: "C",
key_2: "3"
}
];
var CSVOf_arr = arr.map((item) => { return item.key_1 }).join(',')
console.log('Comma seprated values of arr', CSVOf_arr)
OUTPUT: A,B,C
You might want to try this library - Underscore.js. It gives you really helpful methods and works across browsers.
Here you can do it like this -
_.values(person).join(",")
or
_.values(person).join("|")
The Object.values() method returns an array of a given object's own enumerable property values. It can be used to convert object properties to an array which can then be joined using .join(separator) to create the required string with separator defined in join function. But this will cause empty values to be joined as well. So for an object as
var person = {
name: "John",
surname: "Smith",
phone: ""
}
output for
Object.values(person).join(',')
will be
John,Smith,
with an additional "," at the end. To avoid this .filter() can be used to remove empty elements from array and then use join on filtered array.
Object.values(person).filter(Boolean).join(',')
will output
John,Smith
Object.values(person).join('/')
Another way is to use lodash function _.toString()
console.log( _.toString( Object.values( person ) ) );
==> John,Smith,253 689 4555
Check the link below
https://lodash.com/docs/4.17.5#toString
var person = {
name: "John",
surname: "Smith",
phone: "253 689 4555"
}
let personData = ${person.name},${person.surname},${person.phone}
With this `` mark and $ dollar sign you will get the result.
Just use object.values() and use toString() method
Object.values(person).toString()