Return array values which are not duplicates - javascript

var arr = [
{name:"Grace", age: "28"},
{name:"Peter", age: "15"},
{name:"Grace", age: "28"},
{name:"John", age: "16"},
{name:"Prince", age: "19"},
{name:"John", age: "16"}
];
I now want return only those which are unique as below
var new = [
{name:"Peter", age: "15"},
{name:"Prince", age: "19"},
];

You can use Map and reduce
First create a mapper based on name and count repetition of each name
Select only the values where repetition is exactly 1
const arr = [{name:"Grace", age: "28"},{name:"Peter", age: "15"},{name:"Grace", age: "28"},{name:"John", age: "16"},{name:"Prince", age: "19"},{name:"John", age: "16"}];
let mapper = arr.reduce( (op,inp) => {
let {name:key} = inp
op.set(key, op.get(key) || {value: inp, count:0})
op.get(key).count++
return op
},new Map())
let final = [...mapper.values()].reduce((op,{value,count}) => {
if(count === 1){
op.push(value)
}
return op
},[])
console.log(final)

Related

How do I convert an array of objects into an object (dynamically) in JavaScript [duplicate]

This question already has answers here:
Convert array of objects with same property to one object with array values
(6 answers)
Closed 2 months ago.
I have an array of objects that looks like this:
arr = [
{name: "john", age: 23},
{name: "mary", age: 40},
{name: "zack", age: 17}
]
I am trying to convert it into something like this:
{
name: ["john", "mary", "zack"],
age: ['23', 40, 17]
}
i have tried the following
arr.map(item => item.name)
arr.map(item => item.age)
return {names, ages}
and it works fine but this assumes that you already know, beforehand, the keys of the objects you're converting.
I want to be able to load the object keys and corresponding array of values dynamically. Assuming i don't know that the objects in our example array have "name" and "age" as keys.
You could reduce the array and the entries of the object and collect the values in the group of the keys.
const
data = [{ name: "john", age: 23 }, { name: "mary", age: 40 }, { name: "zack", age: 17 }],
result = data.reduce((r, o) => Object.entries(o).reduce((t, [k, v]) => {
if (!t[k]) t[k] = [];
t[k].push(v);
return t;
}, r), {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could get the key of the first element and then map through it. With each, get its corresponded values
const arr = [
{ name: "john", age: 23, gender: "male" },
{ name: "mary", age: 40, gender: "female" },
{ name: "zack", age: 17, gender: "male" },
]
const res = Object.keys(arr[0]).reduce((acc, el) => {
const values = arr.map((item) => item[el])
return { ...acc, [el]: values }
}, {})
console.log(res)
Assuming that each object in your list has the same keys you could get the keys of the first object
const keys = Object.keys(arr[0])
and then map through the keys with your above approach
const returnObj = {}
keys.forEach(key => {
returnObj[key] = arr.map(item => item[key])
})
return returnObj
You can use Object.entries for the mapping.
var arr = [
{name: "john", age: 23},
{name: "mary", age: 40},
{name: "zack", age: 17}
];
var entries = arr.map((item) => Object.entries(item));
var result = {};
entries.forEach(entry => {
entry.forEach(item => {
if (result[item[0]] && result[item[0]].length > 0) {
result[item[0]].push(item[1]);
} else {
result[item[0]] = [item[1]];
}
});
});
console.log(result);
You can make use of Array.reduce and Object.keys.
let arr = [
{name: "john", age: 23},
{name: "mary", age: 40},
{name: "zack", age: 17}
]
const formatData = (data) => {
return data.reduce((res, obj) => {
Object.keys(obj).map(d => {
res[d] = [...(res[d] ||[]), obj[d]]
})
return res;
}, {})
}
console.log(formatData(arr))
You can do this with Ramda
import { mergeWith, concat } from “Ramda”
const mergeConcat = mergeWith(concat)
mergeConcat(arr)

compare an array and object to see if item exists

I have the following:
An array
const myArray = ['john', 'frank', 'paul'];
then I have an array of objects
const myObjectArray = [
{name: 'nery', age: 34, present: true},
{name: 'john', age: 15, present: false},
etc
]
How can I check if myArray value is found in the myObjectArray?
I thought about looping through myArray and then in each iteration looping through myObjectArray to see if it is present. However this seems so 2001.
Any ideas?
You can use the Array.prototype.some and Array.prototype.includes functions.
const names = ['john', 'frank', 'paul'];
const people = [
{name: 'nery', age: 34, present: true},
{name: 'john', age: 15, present: false},
];
const exists = people.some(({ name }) => names.includes(name));
console.log(exists);
Array.prototype.find can find the first element in the provided array that satisfies the provided testing function.
const myArray = ["john", "frank", "paul"];
const myObjectArray = [
{ name: "nery", age: 34, present: true },
{ name: "john", age: 15, present: false },
];
res = myObjectArray.find((o) => myArray.includes(o.name));
console.log(res);
if you want to check if an item from first array is in the name of second array use some to return a boolean
const myArray = ["john", "frank", "paul"];
const myObjectArray = [
{ name: "nery", age: 34, present: true },
{ name: "john", age: 15, present: false },
];
res = myObjectArray.some((o) => myArray.includes(o.name));
console.log(res);
If you want to return the object that has same name from first array use filter
const myArray = ["john", "frank", "paul"];
const myObjectArray = [
{ name: "nery", age: 34, present: true },
{ name: "john", age: 15, present: false },
];
res = myObjectArray.filter((o) => myArray.includes(o.name));
console.log(res);

How can I filter an array of objects with a value from another object?

I want to write a function which takes an array of objects with certain key value pairs as the first argument. And an object with key value pairs as the second argument.
The function should check if the key value pairs from the second argument are found in the array of objects from the first argument.
If so, it should return an array of objects which have the matching name and value pairs.
For example, if I have an array of objects (first argument):
[{name: "Peter", age: 21}, {name: "Kate", age: 18}, {name: "Tihon", age: 17}, {name: "Poopy", age: 17}]
And as the second argument:
{age: 17}
It should return:
[{name: "Tihon", age: 17}, {name: "Poopy", age: 17}]
Because of the matching value age
This is what I have come up with but don't know what to put in the for...in loop:
function checkTheName(list, check) {
let newArr = [];
for(let i = 0; i < list.length; i++){
for(let key in list[i]){
// Stuck here
}
}
return newArr;
}
You can do this with filter and every methods.
let a = [{name: "Peter", age: 21}, {name: "Kate", age: 18}, {name: "Tihon", age: 17}, {name: "Poopy", age: 17}]
let b = {age: 17}
function checkTheName(list, check) {
return list.filter(o => Object.keys(check).every(k => {
return (k in o) && check[k] == o[k]
}))
}
console.log(checkTheName(a, b))
A simple ES6 version with Array.prototype.filter and Array.prototype.every:
const data = [{name: "Peter", age: 21}, {name: "Kate", age: 18}, {name: "Tihon", age: 17}, {name: "Poopy", age: 17}];
const fObj = {age: 17};
const filtred = data.filter(item =>
Object.keys(fObj).every(k => item.hasOwnProperty(k) && item[k] === fObj[k])
);
console.log(filtred);
You can loop over the array and test for that property:
function checkTheName(check, list){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].name === nameKey) {
return myArray[i];
}
}
}
var array =[{name: "Peter", age: 21}, {name: "Kate", age: 18}, {name: "Tihon",
age: 17}, {namenter code heree: "Poopy", age: 17}]
;
var resultObject = checkTheName( array,"string 1");
Use filter to loop over the array.
function findByAge(myArr, obj){
myArr.filter( (item) => {
if(obj.age === item.age){
return item
}
})
}
This will return an array with just the array items that you are looking for.
You can call it following line. Since the function returns a new array. We need to give the new array a name (newArray in this example).
var newArray = findByAge(myArr, obj)
You need to put an if condition comparing the age value of your check object with the age value of the list object. In case, both the values are equal, push object in newArr.
let list = [{ name: "Peter", age: 21 }, { name: "Kate", age: 18 }, { name: "Tihon", age: 17 }, { name: "Poopy", age: 17 }],
check = { age: 17 };
function checkTheName(list, check) {
let newArr = [];
for (let i = 0; i < list.length; i++) {
if (list[i].age == check.age) {
newArr.push(list[i]);
}
}
return newArr;
}
console.log(checkTheName(list, check));
Alternatively, you can also use array#filter.
let list = [{name: "Peter", age: 21}, {name: "Kate", age: 18}, {name: "Tihon", age: 17}, {name: "Poopy", age: 17}],
check = {age: 17},
result = list.filter(o => o.age === check.age);
console.log(result);
var filterobj ={age:17};
var data=[{name: "Tihon", age: 17}, {name: "Poopy", age: 17}]
var newArray = data.filter(function (el) {
return el.age ==filterobj.age;
}

Check if same object exists in an array - Javascript

I have an array of objects as follows
[{name: "jack", age: 10}, {name: "john", age: 15}]
Consider that i have an object
{name: "jack", age: 10}
Now i need to check if this object exist in the array. If all the properties(name, age) of the object matches, then display an alert on the page.
How to accomplish this using pure javascript?
Use Array.some, Array.every and Object.entries
A match will be counted if
There are equal number of keys
There is a match for every key/value pair
var arr = [{name: "jack", age: 10}, {name: "john", age: 15}];
var input = {name: "jack", age: 10};
var result = arr.some((o) => Object.entries(input).every(([k,v]) => o[k] === v) && Object.keys(input).length === Object.keys(o).length);
console.log(result);
Try this:
var data = [{name: "jack", age: 10}, {name: "john", age: 15}];
var input = {name: "jack", age: 10};
for(var i=0;i<data.length;i++)
{
if(data[i].name==input.name && data[i].age == input.age)
{
alert('matched');
break;
}
}
This may be a bad performing method, but it would cover nested object cases with ease. Also this is only suited if ALL key/value pairs must match and that the key/value pairs were defined in the same order.
let c = [{name: "jack", age: 10}, {name: "john", age: 15}],
s = {name: "jack", age: 10};
console.log(c.filter(e => JSON.stringify(s) === JSON.stringify(e)));
You can try this if you don't want to check for index of object inside array object
var obj = [{name: "jack", age: 10}, {name: "john", age: 15}];
var checkObj = {name: "john", age: 15};
if(JSON.stringify(obj).indexOf(JSON.stringify(checkObj)) >= 0){
console.log("Object Available");
}else{
console.log("Object Not Available");
}

Iterating and filtering with ES6/lodash

We have an array of objects like:
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
And an array of a attribute values of the objects in object
const names = ["lisa", "bob"]
How can we find persons with name in the names array using es6, like:
const filteredPersons = [{
name: "lisa",
age: 43
}, {
name: "bob",
age: 67
}];
ES6
Use filter function with predicate and in it check the existence of the name in the names array.
const persons = [
{name: "john", age:23},
{name: "lisa", age:43},
{name: "jim", age:101},
{name: "bob", age:67}
];
const names = ["lisa", "bob"];
const filtered = persons.filter(person => names.includes(person.name));
console.log(filtered);
You can use filter() and inlcudes() to get required result.
DEMO
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
console.log(persons.filter(({
name
}) => names.includes(name)))
.as-console-wrapper { max-height: 100% !important; top: 0; }
I would suggest to use indexOf as includes does not work in IE browser. Also, using {name} works as Destructuring assignment that will hold the value of name property of the object.
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
console.log(persons.filter(({name}) => names.indexOf(name) !== -1))
lodash
You can try following
const persons = [{name: "john", age: 23},
{name: "lisa",age: 43},
{name: "jim", age: 101},
{name: "bob",age: 67}];
const names = ["lisa", "bob"]
const filteredPersons = _.filter(persons, function(person) {
return _.indexOf(names, person.name) !== -1;
});
console.log(filteredPersons);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
In case you want to perform it in n complexity, here is a way to do it:
Create a map with key as person's name and value as person's object.
Map the criteria array and extract the person objects from the map create in step 1.
Here is a working demo:
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
const map = persons.reduce((acc, item) => {
acc[item.name] = item;
return acc;
}, {});
const result = names.map(name => map[name]);
console.log(result);
Note: This solution assumes that only unique person names are in the source array. It needs to be tweaked to handle duplicates.
See Closures, Set, and Array.prototype.filter() for more info.
// Input.
const persons = [{name: "john",age: 23}, {name: "lisa",age: 43}, {name: "jim",age: 101}, {name: "bob",age: 67}]
const names = ["lisa", "bob"]
// Filter.
const filter = (A, B) => (s => A.filter(x => s.has(x.name)))(new Set(B))
// Output.
const output = filter(persons, names)
// Proof.
console.log(output)

Categories

Resources