Updating JSON structure based on id - javascript

I was trying to update the town name in the below-given JSON structure.
"City":[
{
"Name":"Delhi",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd",
"Towns":[
{
"Name":"MG Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
},
{
"Name":"DLF Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
}
]
},
{
"Name":"Pune",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax",
"Towns":[
{
"Name":"Hadapsar",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1x4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax"
},
{
"Name":"Magarpatta",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1f4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bax"
}
]
}
]
I wanted to change the town name from "Hapdasar" to "Viman Nagar" if my cid matches that of Hadapsar Town
Output which I wanted was:
"City":[
{
"Name":"Delhi",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd",
"Towns":[
{
"Name":"MG Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
},
{
"Name":"DLF Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
}
]
},
{
"Name":"Pune",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax",
"Towns":[
{
"Name":"Viman Nagar",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1x4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax"
},
{
"Name":"Magarpatta",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1f4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bax"
}
]
}
]
I was using js map to iterate but was confused about how to replicate the exact structure.

Well, map alone is not enough to solve your problem, since you have two nested arrays. Maybe you can consider the possibility to use maptwice?
For example:
var cid = "c5d58bef-f1c2-4b7c-a6d7-f64df12321ax";
var newName = "Viman Nagar";
City = City.map(function(city) {
city.towns = city.towns.map(function(town) {
if (town.cid === cid)
town.name = newName;
return town;
});
return city;
});

Atribute your object for
let cities = [{
"Name": "Delhi"
...
}]
and then you can map over it
let result = cities.map(city => city.Towns.map(town => {
if (town.Name === "Hadapsar") {
return {
...town,
Name: "Viman Nagar"
}
} else return town
}))

Use Array#map as follows:
Iterate over cities
In every iteration, iterate over Towns. If current town's cid is equal to the one to change, update its Name
const changeTownName = (cities = [], cid, name) =>
cities.map(({ Towns = [], ...props }) => ({
...props,
Towns: Towns.map(town => town.cid === cid
? { ...town, Name: name }
: { ...town }
)
}));
const cities = [
{ Name: 'Delhi', id: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321bd', Towns: [ { Name: "MG Colony", conditionId: '60d1f5eb-0222-4a84-879b-6699b0cfc1a4', cid: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321bd' }, { Name: "DLF Colony", conditionId: '60d1f5eb-0222-4a84-879b-7749b0cfc1a4', cid: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321bd' } ] },
{ Name: 'Pune', id: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321ax', Towns: [ { Name: "Hadapsar", conditionId: '60d1f5eb-0222-4a84-879b-6699b0cfc1x4', cid: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321ax' }, { Name: "Magarpatta", conditionId: '60d1f5eb-0222-4a84-879b-7749b0cfc1f4', cid: 'c5d58bef-f1c2-4b7c-a6d7-f64df12321bax' } ] }
];
console.log( changeTownName(cities, 'c5d58bef-f1c2-4b7c-a6d7-f64df12321ax', 'Viman Nagar') );

If you consider city as cities this code can help you;
cities.forEach(city => {
city.Towns = city.Towns.map(el => {
if (el.Name === 'Hapdasar') {
el.Name = 'Viman Nagar';
}
return el;
})
});

You'll need to loop for each city in your array, and each town in the city. If the cid matches the town's cid, then change it;
const myNewTownName = "Viman Nagar";
const cid = "c5d58bef-f1c2-4b7c-a6d7-f64df12321ax";
for(let i = 0; i < myObj.City.length; i++){
const city = myObj.City[i];
for(let j = 0; j < city.Towns.length; j++){
const town = city.Towns[j];
if(cid === town.cid){
town.Name = myNewTownName;
}
city.town[j] = town;//Updates city with the updated town
}
myObj.City[i] = city; //Updates myObj with the updated city
}

The result can also be obtained using nested .forEach loops to parsing through the outer and inner arrays, with an if block to examine the cid for the target town.
const data = {
"City":[
{
"Name":"Delhi",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd",
"Towns":[
{
"Name":"MG Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
},
{
"Name":"DLF Colony",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1a4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd"
}
]
},
{
"Name":"Pune",
"id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax",
"Towns":[
{
"Name":"Hadapsar",
"conditionId":"60d1f5eb-0222-4a84-879b-6699b0cfc1x4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321ax"
},
{
"Name":"Magarpatta",
"conditionId":"60d1f5eb-0222-4a84-879b-7749b0cfc1f4",
"cid":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bax"
}
]
}
]
} // end data;
const targetCid = "c5d58bef-f1c2-4b7c-a6d7-f64df12321ax"; // cid for Hadapsar;
const objArray = data.City;
objArray.forEach(element => {
element.Towns.forEach(element => {
if (element.cid == targetCid) {
element.Name = "Viman Nagar";
} // end if;
}); // next object in Towns array;
}); // next object in objArray;
document.getElementById('output').textContent = JSON.stringify(data, undefined, 2);
#output {
white-space: pre;
}
<pre id="output"></pre>

Related

How to check if a value in an array is present in other object and accordingly return a new object

I have an array
const dataCheck = ["Rohit","Ravi"];
I have another array of object
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
I want to check if any value in dataCheck is present in the userData and then return a new array with the below data
const newData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit", status: "present" },
{ name: "Ravi", status: "present" },
];
I tried to do something using loops but not getting the expected results
const dataCheck = ["Rohit", "Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" }
];
let newDataValue = {};
let newData = [];
userData.forEach((user) => {
const name = user.name;
dataCheck.forEach((userName) => {
if (name === userName) {
newDataValue = {
name: name,
status: "present"
};
} else {
newDataValue = {
name: name
};
}
newData.push(newDataValue);
});
});
console.log(newData);
My trial gives me repeated results multiple results which is just duplicates
You should use map() and a Set.
const dataCheck = ["Rohit","Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
const set = new Set(dataCheck);
const output = userData.map(data => set.has(data.name) ? ({...data, status: "present"}): data)
console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }
A Set allows for lookups in O(1) time and therefore this algorithm works in O(n) time. If you would use the array for lookups (e.g. using indcludes(), find() etc.) the runtime would be O(n²). Although this will certainly not matter at all for such small arrays, it will become more relevant the larger the array gets.
map() is used here because you want a 1:1 mapping of inputs to outputs. The only thing to determine then is, what the output should be. It is either the input, if the value is not in the Set, or it is the input extended by one property status set to "present". You can check for the presence in a Set using the has() method and can use the ternary operator ? to make the decision which case it is.
const dataCheck = ["Rohit", "Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
// map through every object and check if name property
// exists in data check with help of filter.
// if it exists the length of filter should be 1 so
// you should return { name: el.name, status: "present" } else
// return { name: el.name }
let newData = userData.map((el) => {
if (dataCheck.filter((name) => name === el.name).length > 0) {
return { name: el.name, status: "present" };
} else {
return { name: el.name };
}
});
console.log("newdata: ", newData);
A better approach would be to use map over userData array, find for matching element in dataCheck, if found return matching element + a status key or just return the found element as it is.
const dataCheck = ["Rohit","Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
const getUpdatedObject = () => {
return userData.map(userData => {
const userDetail = dataCheck.find(data => userData.name === data);
if(userDetail) return {userDetail, status:"present"}
else return {...userData}
});
}
console.log(getUpdatedObject())
Working fiddle
Loop through userData, check if name is includes in dataCheck. If true add status 'present'.
const dataCheck = ["Rohit","Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
for (let user of userData) {
if(dataCheck.includes(user.name)) {
user.status = 'present'
}
}
console.log(userData)
You are seeing repeated results due to the second loop dataCheck.forEach((userName) => { as every loop of dataCheck will fire the if/else statement and add something to the final array. However many values you add to dataCheck will be however many duplicates you get.
Only need to loop through one array and check if the value is in the other array so no duplicates get added.
const dataCheck = ["Rohit", "Ravi"];
const userData = [{ name: "Sagar" }, { name: "Vishal" }, { name: "Rohit" }, { name: "Ravi" }];
let newDataValue = {};
let newData = [];
// loop thru the users
userData.forEach((user) => {
// set the user
const name = user.name;
// check if in array
if (dataCheck.indexOf(name) >= 0) {
newDataValue = {
name: name,
status: "present",
};
}
// not in array
else {
newDataValue = {
name: name,
};
}
newData.push(newDataValue);
});
console.log(newData);
So you will do like this :
const dataCheck = ["Rohit","Ravi"];
const userData = [
{ name: "Sagar" },
{ name: "Vishal" },
{ name: "Rohit" },
{ name: "Ravi" },
];
const newUserData = userData.map( user => {
dataCheck.forEach( data => {
if( data === user.name )
user.status = "present";
});
return user;
} );
console.log( newUserData );

A function which return employees with the highest employee count in the department in JavaScript

I am a beginner in programming and solving exercises for logic building.
I have an array of employees.
Like This One (Actual array has more data, this is just an example):
let arr = [
{
name: 'Tom',
department: {
name: 'admin',
},
},
{
name: 'Chris',
department: {
name: 'account',
},
},
];
Now I want to return Employees with the Highest count in the Department
I have counted number of employees per department
const counts = {};
employees.forEach( (employee)=>{
counts[employee.department.name] = (counts[employee.department.name] || 0) + 1;
});
console.log(counts) // { Accounts: 1, admin: 1 }
But I want to return Employees with highest count of with Department and instead of number of employees I want to return each employee object.
This is the expected output:
{
name: 'Employee1'
{
department:'Admin'
}
},
{
name: 'Employee2'
{
department:'Admin'
}
},
{
name: 'Employee3'
{
department:'Admin'
}
}
I just need a guide for what to do next.
Thanks
Instead of number, I store employees by their department in an object (hashmap).
Then to extract the largest one, I've created a function that returns an object having the department and list of employees.
Feel free to run the code below and see the results.
let employees = [
{
name: "Tom",
department: {
name: "admin"
}
},
{
name: "Chris",
department: {
name: "account"
}
}
];
const counts = {};
employees.forEach((employee) => {
counts[employee.department.name] = (
counts[employee.department.name] || []
).concat(employee.name);
});
console.log(counts); // {admin: ['Tom'], account: ['Chris']}
function getLargest(map) {
let max = 0;
let biggestDepartment = null;
Object.entries(map).forEach(([department, arr]) => {
if (max < arr.length) {
max = arr.length;
biggestDepartment = department;
}
});
return {
name: biggestDepartment,
employees: map[biggestDepartment]
}
}
console.log(getLargest(counts))
So my solution is that you first group the employees w.r.t. department and then you can get the department with the highest employee count using the .length property.
const getGroupDepartments = (employees) => {
const groupedDepartments = {};
employees?.forEach((employee) => {
groupedDepartments[employee.department.name] = groupedDepartments[employee.department.name] ?
[...groupedDepartments[employee.department.name], employee] : [employee]
});
return groupedDepartments
}
const getLargestDepartment = (employees) => {
const departments = getGroupDepartments(employees)
let largestDepartment;
for (const department in departments) {
if(largestDepartment?.length < departments[department].length || !largestDepartment){
largestDepartment = departments[department]
}
}
return largestDepartment
}

Cant access data inside nested array of objects

I have an array of objects that I want to iterate over and create a new array of objects.
First I map over the data, then I loop through each object to extract the values. I want to store the Location name and value from each object.
My code is returning null results. I can't change the way data is declared. Can someone help me understand why I keep getting null results?
[
{
"euValue": null,
"asValue": null
}
]
const data = [{
Locations: [{
Location: {
Name: "Europe"
},
Value: "Ireland"
},
{
Location: {
Name: "Asia"
},
Value: "China"
}
]
}];
const formatData = () => {
let formattedData = [];
let euValue, asValue;
formattedData = data.map(location => {
for (const l in location) {
if (location.hasOwnProperty(l)) {
const _this = location[l];
euValue = _this.Location === "Europe" ? _this.Value : null;
asValue = _this.Location === "Asia" ? _this.Value : null;
}
}
return {
euValue,
asValue
};
});
return formattedData;
};
const newData = formatData();
console.log(newData);
Edit
Expected result is
[
{
"euValue": “Ireland”,
"asValue": “China”
}
]
Assuming that inside data you could have multiple objects with a Location array that have only 2 objects (one for Europe and another one for Asia) you should change your function to something like this
const data = [
{
Locations: [
{
Location: { Name: "Europe" },
Value: "Ireland"
},
{
Location: { Name: "Asia" },
Value: "China"
}
]
}
];
const formatData = () => {
// iterate all data objects
return data.map((topLocation) => {
const res = {};
// loop over Location children objects
topLocation.Locations.forEach((location) => {
const { Name } = location.Location;
// decide where to save Value base on the Location.name
if (Name === "Europe") {
res.euValue = location.Value;
} else if (Name === "Asia") {
res.asValue = location.Value;
}
});
return res;
});
};
const newData = formatData();
console.log(newData);
you missing a second loop also you overwriting the usValue and euValue and you better use forEach instead of map in this case.
const data = [{
Locations: [{
Location: {
Name: "Europe"
},
Value: "Ireland"
},
{
Location: {
Name: "Asia"
},
Value: "China"
}
]
}];
const formatData = (data) => {
let formattedData = [],
values = {};
data.forEach(location => {
for (const l in location) {
if (location.hasOwnProperty(l)) {
const _this = location[l];
_this.forEach(el => {
if (el.Location.Name === "Europe") {
values["euValue"] = el.Value || null
}
if (el.Location.Name === "Asia") {
values["asValue"] = el.Value || null
}
})
}
}
});
formattedData.push(values)
return formattedData;
};
console.log(formatData(data))
I don't know what do you want to get from your code but this code may help you.
const data = [{
Locations: [{
Location: {
Name: "Europe"
},
Value: "Ireland"
},
{
Location: {
Name: "Asia"
},
Value: "China"
}
]
}];
const formatData = () => {
let formattedData = [];
formattedData = data.map(location => {
let euValue = [],
asValue = [];
for (const l in location.Locations) {
if (location.Locations.hasOwnProperty(l)) {
const _this = location.Locations[l];
if (_this.Location.Name === "Europe")
euValue.push(_this.Value);
else if (_this.Location.Name === "Asia")
asValue.push(_this.Value);
}
}
return {
euValue,
asValue
};
});
return formattedData;
};
const newData = formatData();
console.log(newData);
I'm sure many of the other answers are fine but the way I did it was to do the classic for loop to iterate over the data. I would have liked to have kept your ternary operators but I think you may need the if/else syntax.
var data = [{
Locations: [{
Location: {
Name: "Europe"
},
Value: "Ireland"
},
{
Location: {
Name: "Asia"
},
Value: "China"
}
]
}];
const formatData = () => {
let formattedData = [];
let euValue, asValue;
formattedData = data.map(location => {
for (const l in location) {
if (location.hasOwnProperty(l)) {
const _this = location[l];
for (let i = 0; i < _this.length; i++) {
if (_this[i].Location.Name === "Europe") {
euValue = _this[i].Value;
} else if (_this[i].Location.Name === "Asia") {
asValue = _this[i].Value;
} else {
euValue, asValue = null;
}
}
}
}
return {
euValue,
asValue
};
});
return formattedData;
};
const newData = formatData();
console.log(newData);
Using Array.prototype.flatMap() might help you get the array you desire in a cleaner way:
const data = [{
Locations: [{
Location: {
Name: "Europe"
},
Value: "Ireland"
},
{
Location: {
Name: "Asia"
},
Value: "China"
}
]
}];
const formatData = () => {
const formattedData = data.flatMap(item => {
const object = {}
item.Locations.map(location => {
const continent = location.Location.Name
let country = {}
if (continent === 'Europe') country = {
euValue: location.Value
}
if (continent === 'Asia') country = {
asValue: location.Value
}
Object.assign(object, country)
});
return object
});
return formattedData;
}
const newData = formatData();
console.log(newData);

Filter selected children from data using Javascript

I try to write a function in JavaScript which filter an array by a selected property (an value).
But it works for 2 level only I do not understand what do I missing.
The data I want to filter:
var data = [
{
name: "john_pc",
children: [
{
name: "sabrina_pc",
children: [
{
name: "sabrina_pc"
},
{
name: "john_pc"
}
]
},
{
name: "john_pc"
}
]
},
{
name: "sabrina_pc"
}
]
The childrenFilter funciton :
const childrenFilter = (childrenData, filters) => {
let filteredData = childrenData.filter(item => {
for (var property in filters) {
var optionalValues = filters[property];
var value = item[property];
if (item.children) {
item.children = childrenFilter(item.children, filters);
}
let hasValue = value == optionalValues;
if (hasValue) {
return true;
}
return false;
}
return false;
}, this);
return filteredData;
}
Calling the function:
As you can see the 'childrenFilter' get an object which the key is property in the data and the key is value I want to keep.
let result = childrenFilter(data, {
"name": "a1"
});
console.log(JSON.stringify(result, null, 2))
The wanted result :
[
{
"name": "john_pc",
"children": [
{
"name": "sabrina_pc",
"children": [
{
"name": "john_pc"
}
]
},
{
"name": "john_pc"
}
]
}
]
Your filter function does not take into account whether or not children elements match the pattern, therefore even though some child elements of the object match the pattern, the object itself is being filtered out.
Here is the explanation:
{
name: "a2", // does not match filter {name:'a1} so is removed alongside child objects
children: [ // gets removed with parent object
{
name: "a2"
},
{
name: "a1"
}
]
}
This should produce the desired output:
const childrenFilter = (childrenData, filters) => {
let filteredData = childrenData.filter(item => {
for (var property in filters) {
var optionalValues = filters[property];
var value = item[property];
if (item.children) {
item.children = childrenFilter(item.children, filters);
}
let hasValue = value == optionalValues;
if (hasValue || item.children.length) { // include item when children mathes the pattern
return true;
}
return false;
}
return false;
}, this);
return filteredData;
}
You could build new array for each step of filtering, beginning from the leaves and check if this contains the wanted value.
This approach generates new objects and does not mutate the original data.
function filter(array, filters) {
return array.reduce((r, o) => {
var children = filter(o.children || [], filters);
return children || Object.entries(filters).every(([k, v]) => o[k] === v)
? (r || []).concat(Object.assign({}, o, children && { children }))
: r;
}, undefined);
}
var data = [{ name: "a1", children: [{ name: "a2", children: [{ name: "a2" }, { name: "a1" }] }, { name: "a1" }] }, { name: "b1" }];
console.log(filter(data, { name: "a1" }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

How can I check if the array of objects have duplicate property values?

I need some help with iterating through array, I keep getting stuck or reinventing the wheel.
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
How could I check if there are two (or more) same name value in array? I do not need a counter, just setting some variable if array values are not unique. Have in mind that array length is dynamic, also array values.
Use array.prototype.map and array.prototype.some:
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){
return valueArr.indexOf(item) != idx
});
console.log(isDuplicate);
ECMA Script 6 Version
If you are in an environment which supports ECMA Script 6's Set, then you can use Array.prototype.some and a Set object, like this
let seen = new Set();
var hasDuplicates = values.some(function(currentObject) {
return seen.size === seen.add(currentObject.name).size;
});
Here, we insert each and every object's name into the Set and we check if the size before and after adding are the same. This works because Set.size returns a number based on unique data (set only adds entries if the data is unique). If/when you have duplicate names, the size won't increase (because the data won't be unique) which means that we would have already seen the current name and it will return true.
ECMA Script 5 Version
If you don't have Set support, then you can use a normal JavaScript object itself, like this
var seen = {};
var hasDuplicates = values.some(function(currentObject) {
if (seen.hasOwnProperty(currentObject.name)) {
// Current name is already seen
return true;
}
// Current name is being seen for the first time
return (seen[currentObject.name] = false);
});
The same can be written succinctly, like this
var seen = {};
var hasDuplicates = values.some(function (currentObject) {
return seen.hasOwnProperty(currentObject.name)
|| (seen[currentObject.name] = false);
});
Note: In both the cases, we use Array.prototype.some because it will short-circuit. The moment it gets a truthy value from the function, it will return true immediately, it will not process rest of the elements.
In TS and ES6 you can create a new Set with the property to be unique and compare it's size to the original array.
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName3' },
{ name: 'someName1' }
]
const uniqueValues = new Set(values.map(v => v.name));
if (uniqueValues.size < values.length) {
console.log('duplicates found')
}
To know if simple array has duplicates we can compare first and last indexes of the same value:
The function:
var hasDupsSimple = function(array) {
return array.some(function(value) { // .some will break as soon as duplicate found (no need to itterate over all array)
return array.indexOf(value) !== array.lastIndexOf(value); // comparing first and last indexes of the same value
})
}
Tests:
hasDupsSimple([1,2,3,4,2,7])
// => true
hasDupsSimple([1,2,3,4,8,7])
// => false
hasDupsSimple([1,"hello",3,"bye","hello",7])
// => true
For an array of objects we need to convert the objects values to a simple array first:
Converting array of objects to the simple array with map:
var hasDupsObjects = function(array) {
return array.map(function(value) {
return value.suit + value.rank
}).some(function(value, index, array) {
return array.indexOf(value) !== array.lastIndexOf(value);
})
}
Tests:
var cardHand = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"three" },
]
hasDupsObjects(cardHand);
// => false
var cardHand2 = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"ten" },
]
hasDupsObjects(cardHand2);
// => true
if you are looking for a boolean, the quickest way would be
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
// solution
var hasDuplicate = false;
values.map(v => v.name).sort().sort((a, b) => {
if (a === b) hasDuplicate = true
})
console.log('hasDuplicate', hasDuplicate)
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
console.log(foundDuplicateName)
Found the first one duplicate name
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
You just need one line of code.
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
let hasDuplicates = values.map(v => v.name).length > new Set(values.map(v => v.name)).size ? true : false;
Try an simple loop:
var repeat = [], tmp, i = 0;
while(i < values.length){
repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp)
}
Demo
With Underscore.js A few ways with Underscore can be done. Here is one of them. Checking if the array is already unique.
function isNameUnique(values){
return _.uniq(values, function(v){ return v.name }).length == values.length
}
With vanilla JavaScript
By checking if there is no recurring names in the array.
function isNameUnique(values){
var names = values.map(function(v){ return v.name });
return !names.some(function(v){
return names.filter(function(w){ return w==v }).length>1
});
}
//checking duplicate elements in an array
var arr=[1,3,4,6,8,9,1,3,4,7];
var hp=new Map();
console.log(arr.sort());
var freq=0;
for(var i=1;i<arr.length;i++){
// console.log(arr[i-1]+" "+arr[i]);
if(arr[i]==arr[i-1]){
freq++;
}
else{
hp.set(arr[i-1],freq+1);
freq=0;
}
}
console.log(hp);
You can use map to return just the name, and then use this forEach trick to check if it exists at least twice:
var areAnyDuplicates = false;
values.map(function(obj) {
return obj.name;
}).forEach(function (element, index, arr) {
if (arr.indexOf(element) !== index) {
areAnyDuplicates = true;
}
});
Fiddle
Adding updated es6 function to check for unique and duplicate values in array. This function is modular and can be reused throughout the code base. Thanks to all the post above.
/* checks for unique keynames in array */
const checkForUnique = (arrToCheck, keyName) => {
/* make set to remove duplicates and compare to */
const uniqueValues = [...new Set(arrToCheck.map(v => v[keyName]))];
if(arrToCheck.length !== uniqueValues.length){
console.log('NOT UNIQUE')
return false
}
return true
}
let arr = [{name:'joshua'},{name:'tony'},{name:'joshua'}]
/* call function with arr and key to check for */
let isUnique = checkForUnique(arr,'name')
checkDuplicate(arr, item) {
const uniqueValues = new Set(arr.map((v) => v[item]));
return uniqueValues.size < arr.length;
},
console.log(this.checkDuplicate(this.dutyExemptionBase, 'CI_ExemptionType')); // true || false
It is quite interesting to work with arrays
You can use new Set() method to find duplicate values!
let's assume you have an array of objects like this...
let myArray = [
{ id: 0, name: "Jhon" },
{ id: 1, name: "sara" },
{ id: 2, name: "pop" },
{ id: 3, name: "sara" }
]
const findUnique = new Set(myArray.map(x => {
return x.name
}))
if(findUnique.size < myArray.length){
console.log("duplicates found!")
}else{
console.log("Done!")
}
const duplicateValues = [{ name: "abc" }, { name: "bcv" }, { name: "abc" }];
const isContainDuplicate = (params) => {
const removedDuplicate = new Set(params.map((el) => el.name));
return params.length !== removedDuplicate.size;
};
const isDuplicate = isContainDuplicate(duplicateValues);
console.log("isDuplicate");

Categories