Handle object array without duplicates - javascript

I use React for my front-end web app. When I call back-end API, I got this array:
[
{
id: 1,
fullname: ABC,
email: abc#gmail.com
...
},
{
id: 2,
fullname: DEF,
email: def#gmail.com
...
},
{
id: 2,
fullname: DEF,
email: def#gmail.com
...
},
{
id: 3,
fullname: GHI,
email: ghi#gmail.com
...
},
{
id: 1,
fullname: ABC,
email: abc#gmail.com
...
}
]
Now, I need to create a new array from this old array but just contain id and fullname and not duplicates. I have try this code:
const oldArray = //this is the array above
const temp = [];
for (let i = 0; i < oldArray .length; i++) {
temp.push({
value: oldArray [i]._id,
display: oldArray [i].fullname
});
}
const newArray = Array.from(new Set(temp));
The result I receive:
[
{
value: 1,
display: ABC
},
{
value: 2,
display: DEF
},
{
value: 2,
display: DEF
},
{
value: 3,
display: GHI
},
{
value: 1,
display: ABC
}
]
As you can see, the result is still duplicated. How can I fix it?

You can use Array#filter with a Set to store ids that were already found.
const arr=[{id:1,fullname:"ABC",email:"abc#gmail.com"},{id:2,fullname:"DEF",email:"def#gmail.com"},{id:2,fullname:"DEF",email:"def#gmail.com"},{id:3,fullname:"GHI",email:"ghi#gmail.com"},{id:1,fullname:"ABC",email:"abc#gmail.com"}];
let ids = new Set, res = arr.filter(x => !ids.has(x.id) && ids.add(x.id));
console.log(res);

const tempArray=[];
const filteredArr = oldArray.filter(value =>{
if(!tempArray.includes(value.id)) {
tempArray.push(value.id)
return true
}
})
Create a tempArray, loop over the array and checks if a value exist in tempArr if not push the value into the tempArr and return true(or value)

I know short answer but, use a Set() on the receiving end. Whenever you add an item to a set, use Set.add - it makes sure if it's a duplicate, it won't be added to the set. Sets have similar capability as arrays, but cannot contain duplicates.

Related

function to Get array and specific start letter and end letter and then return a list of names that starts and end with them

I have a long array of objects. I want to write a function to find for example names that start with specific letter and end with another specific letter and return a list of names that starts and end with them.
I tried some solutions but did not get answer.
Here I use a simple list: and I want a list that name start with "A" and end with "i" or any other case
myList = [{name: "Aji",family: "Ziansi"}, { name: "Alex", family: "ortega"}, {name:"Amandi",family: "Sedirini"}];
Output should be like this:
desiredLiset = [{name: "Aji",family: "Ziansi"}, {name:"Amandi",family: "Sedirini"}];
just in function declaration method.
Any solutions would be appreciated.
We can use Array.filter()
const myList = [{
name: "Aji",
family: "Ziansi"
}, {
name: "Alex",
family: "ortega"
}, {
name: "Amandi",
family: "Sedirini"
}];
const filterList = (list, start, end) => {
return list.filter(obj => {
const name = obj.name;
return name[0] === start && name[name.length - 1] === end;
});
};
const filtered = filterList(myList, "A", "i");
console.log(filtered);
You can use .filter() to get a list of the names you want:
myList = [{name: "Aji",family: "Ziansi"}, { name: "Alex", family: "ortega"}, {name:"Amandi",family: "Sedirini"}];
let desiredLiset = myList.filter(function(n){
return n.name.match(/^A.*i$/i) // Names that begin with 'A' and end with 'i'
});
console.log(desiredLiset)
// 0: Object { name: "Aji", family: "Ziansi" }
// ​1: Object { name: "Amandi", family: "Sedirini" }
Try this:
myList = [{name: "Aji",family: "Ziansi"}, { name: "Alex", family: "ortega"}, {name:"Amandi",family: "Sedirini"}];
const start='A'
const end='i'
const startEndRE = new RegExp(`^${start}.*${end}$`)
myList.filter(item=>(
startEndRE.test(item.name)
))
// Result
// [
// { name: 'Aji', family: 'Ziansi' },
// { name: 'Amandi', family: 'Sedirini' }
// ]
It is also possible to do using endsWith() and startsWith()
try:
const myList = [{ name: "Aji", family: "Ziansi" }, { name: "Alex", family: "ortega" }, { name: "Amandi", family: "Sedirini" }];
const newlist = myList.filter((obj) => obj.name.startsWith('A') && obj.name.endsWith('i'));
console.log(newlist);

How to add label to js array?

Hi I am looking to create an array that looks similar to this
const userList = {
123: "Tom",
124: "Michael",
125: "Christin",
};
it contains both value and label, what I tried so far
let raw = []
for (let x in data) {
raw.push(data[x].facility_name : data[x].id)
}
but it didn't work because "," was expected, if someone can help please
You are confusing arrays and objects. You need to add a key to an object not push. I kept it as a for in loop, but a for of loop would make more sense.
const data = [
{ id: 1, facility_name: "foo1" },
{ id: 2, facility_name: "foo2" },
{ id: 3, facility_name: "foo3" }
];
let raw = {};
for (let x in data) {
raw[data[x].id] = data[x].facility_name;
}
console.log(raw);
How I would code it using reduce.
var data = [
{ id: 1, facility_name: "foo1" },
{ id: 2, facility_name: "foo2" },
{ id: 3, facility_name: "foo3" }
];
const raw = data.reduce(function (acc, facility) {
acc[facility.id] = facility.facility_name;
return acc;
}, {})
console.log(raw);
IF your data has nested objects then you might do this:
let raw = {};
for(x in data)
{
raw[data[x].facility_name] = data[x].id;
}
This is useful when you want to get rid of duplicates.

Filter array items using forEach

I have one question about filter array in forEach. So I would like filter (bigger than in example) array using outside variable filterKey. I think that my function is correct by after filtered newArr is undefined. Could you explain what is incorrect?
var filterKey = 123456,
var array = [{
ratings:{ users:[id: 123456]}, user: xyz
},
{
ratings:{users:[id:9787389023]}, user:zyx
}],
And my filter function
var newArr = array.forEach((ele) =>
ele.ratings.users.filter((newEl) =>
newEl.id == filterKey))
Use array.filter method
let array = [
{
id: 123456, user: 'xyz'
},
{
id:9787389023, user: 'zyx'
},
{
id: 123456, user: 'che'
}
]
let newArray = array.filter((element) => element.id === 123456)
console.log(newArray)
Use .filter and you'll be able to filter your result set without using foreach since it'll loop across the array.
var find = 123456;
var arr = [
{
id: 123456,
user: 'john'
},
{
id: 9787389023,
user: 'leah'
}
];
var results = arr.filter(function(node) {
return node.id === find;
});
console.log(results);

Javascript: Filter array of objects

What am I doing wrong here?
var locations = [
{ id: 1, name: 'N'},
{ id: 2, name: 'P'}
]
var employee = { location_id: 1 }
locations.filter((location) => {
return location.id == employee.location_id
});
console.log(locations);
this returns undefined when I'm trying to make it return { id: 1, name: 'N'}.
filter() function is not mutable - which means it returns a new array with the filtered objects and do not 'mutate' the original array - you must assign it to another variable - see demo below:
locations = [
{ id: 1, name: 'N'},
{ id: 2, name: 'P'}
]
employee = { location_id: 1 }
var result = locations.filter((location) => {
return location.id == employee.location_id
})
console.log(result);
You need a variable for the result of filtering with Array#filter
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
var locations = [
{ id: 1, name: 'N'},
{ id: 2, name: 'P'}
],
employee = { location_id: 1 },
result = locations.filter((location) => {
return location.id == employee.location_id
});
console.log(result);
You need to store the result of .filter(). It doesn't mutate the original array.
On a side note, you can shorten your callback function by removing the curly brackets and return statement.
locations = locations.filter(loc => loc.id == employee.location_id);

How can I get a unique array based on object property using underscore

I have an array of objects and I want to get a new array from it that is unique based only on a single property, is there a simple way to achieve this?
Eg.
[ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ]
Would result in 2 objects with name = bill removed once.
Use the uniq function
var destArray = _.uniq(sourceArray, function(x){
return x.name;
});
or single-line version
var destArray = _.uniq(sourceArray, x => x.name);
From the docs:
Produces a duplicate-free version of the array, using === to test object equality. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iterator function.
In the above example, the function uses the objects name in order to determine uniqueness.
If you prefer to do things yourself without Lodash, and without getting verbose, try this uniq filter with optional uniq by property:
const uniqFilterAccordingToProp = function (prop) {
if (prop)
return (ele, i, arr) => arr.map(ele => ele[prop]).indexOf(ele[prop]) === i
else
return (ele, i, arr) => arr.indexOf(ele) === i
}
Then, use it like this:
const obj = [ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ]
obj.filter(uniqFilterAccordingToProp('abc'))
Or for plain arrays, just omit the parameter, while remembering to invoke:
[1,1,2].filter(uniqFilterAccordingToProp())
If you want to check all the properties then
lodash 4 comes with _.uniqWith(sourceArray, _.isEqual)
A better and quick approach
var table = [
{
a:1,
b:2
},
{
a:2,
b:3
},
{
a:1,
b:4
}
];
let result = [...new Set(table.map(item => item.a))];
document.write(JSON.stringify(result));
Found here
You can use the _.uniqBy function
var array = [ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }, { id: 1, name: 'bill' },{ id: 2, name: 'bill' } ];
var filteredArray = _.uniqBy(array,function(x){ return x.id && x.name;});
console.log(filteredArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>
In the above example, filtering is based on the uniqueness of combination of properties id & name.
if you have multiple properties for an object.
then to find unique array of objects based on specific properties, you could follow this method of combining properties inside _.uniqBy() method.
I was looking for a solution which didn't require a library, and put this together, so I thought I'd add it here. It may not be ideal, or working in all situations, but it's doing what I require, so could potentially help someone else:
const uniqueBy = (items, reducer, dupeCheck = [], currentResults = []) => {
if (!items || items.length === 0) return currentResults;
const thisValue = reducer(items[0]);
const resultsToPass = dupeCheck.indexOf(thisValue) === -1 ?
[...currentResults, items[0]] : currentResults;
return uniqueBy(
items.slice(1),
reducer,
[...dupeCheck, thisValue],
resultsToPass,
);
}
const testData = [
{text: 'hello', image: 'yes'},
{text: 'he'},
{text: 'hello'},
{text: 'hell'},
{text: 'hello'},
{text: 'hellop'},
];
const results = uniqueBy(
testData,
item => {
return item.text
},
)
console.dir(results)
In case you need pure JavaScript solution:
var uniqueProperties = {};
var notUniqueArray = [ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ];
for(var object in notUniqueArray){
uniqueProperties[notUniqueArray[object]['name']] = notUniqueArray[object]['id'];
}
var uniqiueArray = [];
for(var uniqueName in uniqueProperties){
uniqiueArray.push(
{id:uniqueProperties[uniqueName],name:uniqueName});
}
//uniqiueArray
unique array by id property with ES6:
arr.filter((a, i) => arr.findIndex(b => b.id === a.id) === i); // unique by id
replace b.id === a.id with the relevant comparison for your case

Categories

Resources