I have this array (java script array of objects)
users=[{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884}
{name:'arrow',age:30,id:99},
{name:'apple',age:50,id:999}
{name:'bow',age:50,id:9669}]
I want to remove second occurrence of same name , in this case , I want to remove {name:'arrow',age:30,id:99} and {name:'bow',age:50,id:9669} and retain first occurrences{name:'arrow',age:50,id:444} and {name:'bow',age:66,id:884}
Resulting array should be :
users= [{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884},
{name:'apple',age:50,id:999}]
const users = [
{ name: 'arrow', age: 50, id: 444 },
{ name: 'bow', age: 66, id: 884 },
{ name: 'arrow', age: 30, id: 99 },
{ name: 'apple', age: 50, id: 999 },
{ name: 'bow', age: 50, id: 9669 }
]
const uniqueUsers = users.reduce((acc, user) => {
if (!acc.find(u => u.name === user.name)) {
acc.push(user)
}
return acc
}, [])
I'd go with the approach of array.filter:
function removeDuplicateKeyFromArray(arrayOfObjects,keyName){
keyHolder = {}
arrayOfObjects.filter((obj)=>{
if(keyHolder[obj.keyName]){
return false
}
keyHolder[obj.keyName] = 1 //or true
return true
})
}
I would create 2 for-loops, to filter out any duplicates.
here's my code:
let users = [{name:'arrow',age:50,id:444},
{name:'bow',age:66,id:884},
{name:'arrow',age:30,id:99},
{name:'apple',age: 50,id: 990},
{name:'bow',age: 50,id: 9669}]
for (let i = 0; i < users.length; i++) {
for(let x = 0; i < users.length; i++) {
if(users[i].name == users[x].name) {
users.splice(users[x], 1)
}
}
}
Related
So first, here's a simple snippet to demonstrate what I mean exactly, and what I have tried.
let array_1 = [
{ id: 1, name: 'Peter' },
{ id: 2, name: 'John' },
{ id: 3, name: 'Andrew' },
{ id: 4, name: 'Patrick' },
{ id: 5, name: 'Brian' }
];
let array_2 = [
{ id: 1, name: 'not Peter' },
{ id: 80, name: 'not John' },
{ id: 3, name: 'not Andrew' },
{ id: 40, name: 'not Patrick' },
{ id: 5, name: 'not Brian' }
];
array_1.forEach(item_1 => {
for (let i = 0; i < array_2.length; i++) {
item_1.matches = array_2[i].id === item_1.id
}
});
console.log('matched_array', array_1);
The goal here is to add the matches property to each object in array_1 and set it to true/false, based on whether the id matches with any other id from array_2.
In this current example, the result of the matches properties should go like this: true - false - true - false - true. But my current code only sets this property correctly in the last element of the array (array_1).
Obviously it's because my code is not entirely correct, and that's where I'm stuck.
You could first create one object with reduce method that you can then use as a hash table to check if the element with the same id exists in the array 2.
let array_1=[{"id":1,"name":"Peter"},{"id":2,"name":"John"},{"id":3,"name":"Andrew"},{"id":4,"name":"Patrick"},{"id":5,"name":"Brian"}, {"id":6,"name":"Joe"}]
let array_2=[{"id":1,"name":"not Peter"},{"id":80,"name":"not John"},{"id":3,"name":"not Andrew"},{"id":40,"name":"not Patrick"},{"id":5,"name":"not Brian"}]
const o = array_2.reduce((r, e) => (r[e.id] = true, r), {})
const result = array_1.map(e => ({ ...e, matches: o[e.id] || false}))
console.log(result)
I would first collect the ids of array_2 in a Set, sets have a O(1) lookup time so checking if an id is in this set is fast. Then iterate over array_1 and check if the id is present in the created set using has().
let array_1 = [
{ id: 1, name: 'Peter' },
{ id: 2, name: 'John' },
{ id: 3, name: 'Andrew' },
{ id: 4, name: 'Patrick' },
{ id: 5, name: 'Brian' }
];
let array_2 = [
{ id: 1, name: 'not Peter' },
{ id: 80, name: 'not John' },
{ id: 3, name: 'not Andrew' },
{ id: 40, name: 'not Patrick' },
{ id: 5, name: 'not Brian' }
];
const array_2_ids = new Set(array_2.map(item_2 => item_2.id));
array_1.forEach(item_1 => item_1.matches = array_2_ids.has(item_1.id));
console.log('matched_array', array_1);
Your current code doesn't work because the for-loop will update the item_1.matches property for each element in array_2. This means you are overwriting the property each time. This in turn will effectivly result in item_1 only being checked against the last item in array_2.
To make your code work this:
array_1.forEach(item_1 => {
for (let i = 0; i < array_2.length; i++) {
item_1.matches = array_2[i].id === item_1.id
}
});
Should be changed into this:
array_1.forEach(item_1 => {
for (let i = 0; i < array_2.length; i++) {
if (array_2[i].id === item_1.id) {
item_1.matches = true;
return;
}
}
item_1.matches = false;
});
Hi I have list of values in array as bellow
var users = [{
name: 'John',
email: 'johnson#mail.com',
age: 25,
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
},
{
name: 'John',
email: 'johnson#mail.com',
age: 25,
}];
I should find duplicates row from the above array (need to compare all the fields name, email, and age)
I have used some function to find a duplicate value as below but need to pass multiple conditions in it. How to do that
const unique = new Set();
const showError = this.users.some(element => unique.size === unique.add(element.name).size);
As I have passed the name I need to verify email and age. How to do that
Maintain counter while checking equality, as every object will be equal with same object, hence check if counter is greater than 1 for getting status.
const status = users.some(user => {
let counter = 0;
for (const iterator of users) {
if (iterator.name === user.name && iterator.email === user.email && iterator.age === user.age) {
counter += 1;
}
}
return counter > 1;
});
var users = [
{
name: 'John',
email: 'johnson#mail.com',
age: 25,
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
},
{
name: 'John',
email: 'johnson#mail.com',
age: 25,
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
},,
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
},
{
name: 'Harry',
email: 'harry#mail.com',
age: 23,
},
{
name: 'Kane',
email: 'kane#mail.com',
age: 65,
},
{
name: 'Ron',
email: 'ron#mail.com',
age: 65,
},
{
name: 'Ron',
email: 'ron#mail.com',
age: 65,
}
];
// complexity of this function is n where n is the no of users
var data = uniqueData(users, 'email');
console.log(data)
function uniqueData(array, key) {
// create new objects for use
var uniqueArray = [];
var map = new Map();
// loop throught array
array.forEach((user,index) => {
// first item is always unique add to unique whithout check
if(index == 0) {
// using map set first item in map key and value is dynamic which we can set
map.set(array[index].email, array[index].email);
uniqueArray.push(array[index]);
}
//check if the key already exists if exists do not push else push
if (!map.get(user[key])) {
map.set(user[key], user[key]);
uniqueArray.push(user);
}
});
return uniqueArray;
}
Use below code for remove duplicates
function removeDuplicates(array, key) {
let lookup = {};
return array.filter(obj => !lookup[obj[key]] && lookup[obj[key]] = true);
}
Try this:
const showError: boolean = Array.from(new Set(users.map(user => JSON.stringify(user)))).length != users.length;
var frequency = users.reduce(function(seen, currentItem) {
if (currentItem in seen) {
seen[currentItem] = seen[currentItem] + 1;
} else {
seen[currentItem] = 1;
}
return seen;
}, {});
for (var key in frequency) {
if (frequency[key] > 1) {
result.push(key.split(",").map(function(currentItem) {
return parseInt(currentItem);
}));
}
}
console.log(result);
hope this will help you
Updated Version of the Problem: my goal is to get the indexes of the of the element of this array, with the condition that the subelement param_name of key params will define the index of the object. For instance, object with key name 'caller1' should have a default index of 0, but since param_name is 'caller2' it will take index 1; similarly object 3 with key name 'caller3' will take index 0 since param_name is 'caller1'. For object 2 with key name 'caller2' since param_name is same as key name caller2 it will retain its default index of 1.
const array1 = [{
name: 'caller1',
cost: 12,
params:[{param_name:'caller2',apparatus:'fittings'}]
},
{
name: 'caller2',
cost: 2,
params:[{param_name:'caller2',apparatus:'fittings'}]
},
{
name: 'caller3',
cost: 12,
params:[{param_name:'caller1',apparatus:'valves'}]
}
];
const results = []
for (let j=0; j<array1.length;j++){
results[j] = array1[j].findIndex(a => a.name==array1[j].name);
}
console.log(results);
You need to take the property from params and use that as a search parameter to use when looping over the main array
var indexes = array1.map(element => {
var nameToCheck = element.params[0].param_name;
for (let i = 0; i < array1.length; i++) {
if (array1[i].name == nameToCheck) {
return i;
}
}
})
Demo
const array1 = [{
name: 'caller1',
cost: 12,
params: [{
param_name: 'caller2',
apparatus: 'fittings'
}]
},
{
name: 'caller2',
cost: 2,
params: [{
param_name: 'caller2',
apparatus: 'fittings'
}]
},
{
name: 'caller3',
cost: 12,
params: [{
param_name: 'caller1',
apparatus: 'valves'
}]
}
];
var indexes = array1.map(element => {
var nameToCheck = element.params[0].param_name;
for (let i = 0; i < array1.length; i++) {
if (array1[i].name == nameToCheck) {
return i;
}
}
})
console.log(indexes);
Note that if params actually contains more than 1 element you would need to account for that and decide which one you need to use and change the element.params[0].param_name; line accordingly
You could take a Map and map the indices.
const
array = [{ name: 'caller1', cost: 12, params: [{ param_name: 'caller2', apparatus: 'fittings' }] }, { name: 'caller2', cost: 2, params: [{ param_name: 'caller2', apparatus: 'fittings' }] }, { name: 'caller3', cost: 12, params: [{ param_name: 'caller1', apparatus: 'valves' }] }],
map = new Map(array.map(({ name }, i) => [name, i])),
result = array.map(({ params: [{ param_name }] }) => map.get(param_name));
console.log(result);
I have this array of objects:
var frequencies = [{id:124,name:'qqq'},
{id:589,name:'www'},
{id:45,name:'eee'},
{id:567,name:'rrr'}];
And this array of id:
var idArray = [124,45];
I need create function that return array of string that contains value of the name that has idArray.
for example, the result according to the arrays above(frequencies and idArray) :
var result = var frequencies = ['qqq','eee'];
How can I implement this function?
Use Array#filter and Array#map methods.
var res = frequencies
//filter out object array
.filter(function(v) {
return idArray.indexOf(v.id) > -1;
})
// generate result arrray from filtered array
.map(function(v) {
return v.name
});
var frequencies = [{
id: 124,
name: 'qqq'
}, {
id: 589,
name: 'www'
}, {
id: 45,
name: 'eee'
}, {
id: 567,
name: 'rrr'
}];
var idArray = [124, 45];
var res = frequencies
//filter out object array
.filter(function(v) {
return idArray.indexOf(v.id) > -1;
})
// generate result arrray from filtered array
.map(function(v) {
return v.name
});
// with ES6 arrow function
//var res = frequencies.filter(v => idArray.indexOf(v.id) > -1).map(v => v.name);
console.log(res);
The same code with ES6 arrow function.
var res = frequencies
.filter(v => idArray.indexOf(v.id) > -1)
.map(v => v.name);
var frequencies = [{
id: 124,
name: 'qqq'
}, {
id: 589,
name: 'www'
}, {
id: 45,
name: 'eee'
}, {
id: 567,
name: 'rrr'
}];
var idArray = [124, 45];
var res = frequencies
.filter(v => idArray.indexOf(v.id) > -1)
.map(v => v.name);
console.log(res);
Or use a simple for loop
var res = [];
for (var i = 0; i < frequencies.length; i++) {
// check the id value present in array
// push the name property value if id present in array
if (idArray.indexOf(frequencies[i].id) > -1) {
res.push(frequencies[i].name);
}
}
var frequencies = [{
id: 124,
name: 'qqq'
}, {
id: 589,
name: 'www'
}, {
id: 45,
name: 'eee'
}, {
id: 567,
name: 'rrr'
}];
var idArray = [124, 45],
res = [];
for (var i = 0; i < frequencies.length; i++) {
// check the id value present in array
// push the name property value if id present in array
if (idArray.indexOf(frequencies[i].id) > -1) {
res.push(frequencies[i].name);
}
}
console.log(res);
ESNEXT code
frequencies
.filter(({id}) => idArray.includes(id))
.map(({name}) => name)
I am trying to combine/merge 2 array of objects by key in my case id.
Objective:
I am expecting a results where I would have array containing all objects with ids 1,2,3,4 as per example
Order of merging should not affect number of objects in result for example combine(arr1,arr2) or combine(arr2,arr1) should have array with same number of objects
Order of merging can only affect resulting object for example in case of combine(arr1,arr2) arr2 key,values pair can override arr1 key,values just like deep jquery extend $.extend( true, arr1ObJ,arr2ObJ );
JSFIDDLE: https://jsfiddle.net/bababalcksheep/u2c05nyj/
Sample Data:
var arr1 = [{
id: 1,
name: "fred",
title: "boss"
}, {
id: 2,
name: "jim",
title: "nobody"
}, {
id: 3,
name: "bob",
title: "dancer"
}];
var arr2 = [{
id: 1,
wage: "300",
rate: "day"
}, {
id: 2,
wage: "10",
rate: "hour"
}, {
id: 4,
wage: "500",
rate: "week"
}];
var Result = [{
"id": 1,
"name": "fred",
"title": "boss",
"wage": "300",
"rate": "day"
}, {
"id": 2,
"name": "jim",
"title": "nobody",
"wage": "10",
"rate": "hour"
}, {
id: 3,
name: "bob",
title: "dancer"
}, {
id: 4,
wage: "500",
rate: "week"
}];
Here's a solution. It basically goes through each element of arr2 and checks to see if there's an element with a matching ID arr1. If so, it updates the matching element in arr1 with arr2's values. If there is no match, it simply pushes the element in arr2 onto arr1.
var arr1 = [{id: 1,name: 'fred',title: 'boss'},
{id: 2,name: 'jim',title: 'nobody'},
{id: 3,name: 'bob',title: 'dancer'}];
var arr2 = [{id: 1,wage: '300',rate: 'day'},
{id: 2,wage: '10',rate:'hour'},
{id: 4,wage: '500',rate: 'week'}];
function combineArrays(arr1, arr2) {
for(var i = 0; i < arr2.length; i++) {
// check if current object exists in arr1
var idIndex = hasID(arr2[i]['id'], arr1);
if(idIndex >= 0){
//update
for(var key in arr2[i]){
arr1[idIndex][key] = arr2[i][key];
}
} else {
//insert
arr1.push(arr2[i]);
}
}
return arr1;
}
//Returns position in array that ID exists
function hasID(id, arr) {
for(var i = 0; i < arr.length; i ++) {
if(arr[i]['id'] === id)
{
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
}, {
id: 2,
name: 'jim',
title: 'nobody'
}, {
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
}, {
id: 2,
wage: '10',
rate: 'hour'
}, {
id: 4,
wage: '500',
rate: 'week'
}];
function combineArrays(arr1, arr2) {
for (var i = 0; i < arr2.length; i++) {
var idIndex = hasID(arr2[i]['id'], arr1);
if (idIndex >= 0) {
for (var key in arr2[i]) {
arr1[idIndex][key] = arr2[i][key];
}
} else {
arr1.push(arr2[i]);
}
}
return arr1;
}
function hasID(id, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i]['id'] === id) {
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
How about something along the lines of this:
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
used as
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
var arr1 = [
{ id: 1, name: 'fred', title: 'boss' },
{ id: 2, name: 'jim', title: 'nobody' },
{ id: 3, name: 'bob', title: 'dancer' }
];
var arr2 = [
{ id: 1, wage: '300', rate: 'day' },
{ id: 2, wage: '10', rate: 'hour' },
{ id: 4, wage: '500', rate: 'week' }
];
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
output(combine);
//
//
//
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>