Add new property to object if found in array - javascript

I have an array of objects and each object has an id. I have another array with id values. If an objects id is found in arrayOfIds, I would like to add new property called found and set to true. I was thinking of using findIndex as a possible function to use here.
const arrayOfObjects = [ { id: '123' }, { id: '456' }, { id: '789' } ]
const arrayOfIds = ['456']
Expected Output
const arrayOfObjects = [ { id: '123' }, { id: '456', found: true }, { id: '789' } ]

const arrayOfObjects = [ { id: '123' }, { id: '456' }, { id: '789' } ]
const arrayOfIds = ['456']
arrayOfObjects.map((object) => {
if(arrayOfIds.includes(object.id)) {
object.found = true;
}
})
console.log(arrayOfObjects);

I think it would make sense to convert your arrayOfIds to a Set to allow O(1) lookup.
const ids = new Set(arrayOfIds);
const augmentedObjects = arrayOfObjects.map(obj => {
if (ids.has(obj.id)) {
obj.found = true;
}
return obj;
});

You can create a Set from the array and use Array#map along with Set#has.
const arrayOfObjects = [ { id: '123' }, { id: '456' }, { id: '789' } ]
const ids = new Set(['456']);
const res = arrayOfObjects.map(o => ({...o, ...ids.has(o.id) && {found: true}}));
console.log(res);

You can map through the objects and spread the object with the found property.
const output = arrayOfObjects.map((obj) => {
if (arrayOfIds.includes(obj.id)) {
return { ...obj, found: true };
}
return obj;
});

You could do it by creating a lookup object. Create the lookup object from arrayOfIds and use that lookup object when traversing arrayOfObjects array and make certain changes.
const arrayOfObjects = [{ id: '123' }, { id: '456' }, { id: '789' }];
const arrayOfIds = ['456'];
const lookup = Object.fromEntries(arrayOfIds.map((x) => [x, { found: true }]));
const ret = arrayOfObjects.map((x) => ({ ...x, ...lookup[x.id] }));
console.log(ret);

Just run a map over the array of objects, and use the includes to add show: true by spreading the existing object else return the original object.
You could try something like this
const arrayOfObjects = [{ id: "123" }, { id: "456" }, { id: "789" }];
const arrayOfIds = ["456"];
const result = arrayOfObjects.map((item) => {
if (arrayOfIds.includes(item.id)) {
return {
...item,
found: true
};
}
return item;
});
console.log(result);

Related

check array of objects if specific value is unique across all the array

I have an array like this
const arr = [{ name: 'sara' }, { name: 'joe' }];
and i want to check if name is unique across the array so
const arr = [{ name: 'sara' }, { name: 'joe' }];//sara is unique //true
const arr = [{ name: 'sara' }, { name: 'sara' },{ name: 'joe' }];//sara is unique //false
i know there's array.some but it doesn't help in my situation
whats is the best way to achieve that using javascript thanks in advance
You could take a single loop and a Set for seen value.
isUnique is a function which takes a property name and returns a function for Array#every.
const
isUnique = (key, s = new Set) => o => !s.has(o[key]) && s.add(o[key]),
a = [{ name: 'sara' }, { name: 'joe' }],
b = [{ name: 'sara' }, { name: 'sara' }, { name: 'joe' }];
console.log(a.every(isUnique('name'))); // true
console.log(b.every(isUnique('name'))); // false
i have this implementation and it dose the job
const arr = [{ name: "salah" }, { name: "joe" }];
let bols = [];
arr.forEach((item1, i1) => {
arr.forEach((item2, i2) => {
if (i1 !== i2) {
bols.push(item2.name === item1.name);
}
});
});
bols.some((item) => item === true);

How to convert array of objects into enum like key value pair in javascript?

I have an array
const a = [
{ name: "read-web-courses" },
{ name: "example" },
{ name: "t_gql" },
{ name: "ddddd" },
];
I am trying it to reduce it to the below given output , However I am stuck
Output
{0:"read-web-courses",1:"example",2:"t_gql",3:"ddddd"}
You could map the wanted property and assign the pairs to the object.
const
array = [{ name: "read-web-courses" }, { name: "example" }, { name: "t_gql" }, { name: "ddddd" }],
result = Object.assign({}, array.map(({ name }) => name));
console.log(result);
You can use Array.reduce like below.
const a = [
{ name: "read-web-courses" },
{ name: "example" },
{ name: "t_gql" },
{ name: "ddddd" },
];
const convert = arr => (
arr.reduce((total, value, index) => {
total[index] = value.name;
return total;
}, {})
)
console.log(convert(a));
This is accomplished using Array#reduce, where you can use the index from the reduce callback as the key of the new object:
const a = [ { name: "read-web-courses" }, { name: "example" }, { name: "t_gql" }, { name: "ddddd" }];
const res = a.reduce((r, o, i) => {
r[i] = o.name;
return r;
}, {});
console.log(res);
Also one more approach using Object#fromEntries and Array#map, where each object is converted to an array of key, value pairs:
const a = [ { name: "read-web-courses" }, { name: "example" }, { name: "t_gql" }, { name: "ddddd" }];
const res = Object.fromEntries(a.map((o, i) => [i, o.name]));
console.log(res)

How to filter the array using the content of another array?

The code looks as following:
inputArray = [
{ name: 'file1.jpg' },
{ name: 'file1.jpg' },
{ name: 'file2.jpg' },
{ name: 'file3.jpg' },
{ name: 'file4.jpg' }
]
filteringArray = ['file1', 'file2']
const outputArray = inputArray.filter( ? )
I need to filter the inputArrat so that the outputArray should contain only objects, which filenames ('name' property) are in filteringArray.
outputArray = [
{ name: 'file1.jpg' },
{ name: 'file2.jpg' }
]
I've worked so far with simpler filtering conditions, but I'm not sure how to solve this.
You can use .some() with .starsWith() to return true if the objects name starts with a file name present in your array like so:
const inputArray = [
{ name: 'file1.jpg' },
{ name: 'file2.jpg' },
{ name: 'file3.jpg' },
{ name: 'file4.jpg' }
];
const filteringArray = ['file1', 'file2'];
const outputArray = inputArray.filter(({name}) => filteringArray.some(file => name.startsWith(file)));
console.log(outputArray);
If you're looking for a solution which has a better time complexity (and has no duplicates), you could create a Map, which stores prefix file names as keys and the literal objects as values. Then, you can .map() your filteringArray using this map:
const inputArray = [
{ name: 'file1.jpg' },
{ name: 'file1.jpg' },
{ name: 'file2.jpg' },
{ name: 'file3.jpg' },
{ name: 'file4.jpg' }
]
const filteringArray = ['file1', 'file2'];
const lut = new Map(inputArray.map(({name}) => [name.split('.').shift(), {name}]));
const outputArray = filteringArray.map(f => lut.get(f));
console.log(outputArray);
You can use combination of filter and includes!
const inputArray = [
{ name: 'file1.jpg' },
{ name: 'file2.jpg' },
{ name: 'file3.jpg' },
{ name: 'file4.jpg' }
]
const filteringArray = ['file1', 'file2']
const outputArray = inputArray.filter((person) => filteringArray.includes(person.name.split(".")[0]))
console.log(outputArray);
You can use a simple function to do filter operation in the array using the filter logic array items as below.
var outputArray = [];
var inputArray = [
{ name: 'file1.jpg' },
{ name: 'file1.jpg' },
{ name: 'file2.jpg' },
{ name: 'file3.jpg' },
{ name: 'file4.jpg' }
];
var filteringArray = ['file1', 'file2'];
function filterItems(arr, query) {
arr.filter(function(el) {
query.forEach(function(item){
if(el.name.toLowerCase().indexOf(item.toLowerCase()) !== -1){
outputArray.push(el.name);
}
});
});
}
filterItems(inputArray, filteringArray);
console.log(remove_duplicates(outputArray));
function remove_duplicates(arr) {
var obj = {};
var ret_arr = [];
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = true;
}
for (var key in obj) {
ret_arr.push(key);
}
return ret_arr;
}
NOTE: Updated the code, Now input array is having duplicate values. And in output array, there is no duplicate entry as I removed duplicates using a function (Remove duplicate values from JS array)

React How to add new dynamic key to existing state?

I have getting the data from database as an array.
So now I'm getting array like this:
orders:[
{
_id:1,
name: honda,
}
{
_id:2,
name: suzuki,
}
{
_id:3,
name: audi,
}
]
So my question is how can I attach new key value to the array, so It needs to look like this:
orders:[
{
_id:1,
name: honda,
opened:true,
}
{
_id:2,
name: suzuki,
opened:true,
}
{
_id:3,
name: audi,
opened:true,
}
]
For now I'm trying with this code, but this doesn't work:
getOrders(orders).then(response => {
response.map(itm=>{
const ordersData=[...itm]
const opened={opened:true}
this.setState({
openedOrders: [ordersData,opened]
})
})
})
openedOrders is new state object that I create.
What is best solution for this?
Thanks
Your map should look like this. (Note the return statement in map function)
orders.map(item=> {
return {...item, opened:true}
})
So your function could look like
getOrders(orders).then(response => {
let openedOrders = orders.map(item=> {
return {...item, opened:true}
})
this.setState({
openedOrders
})
})
Assuming response contains the first array in your OP:
getOrders(orders).then(response => {
const openedOrders = response.map(order => ({ ...order, open: true}))
this.setState({ openedOrders } )
})
response.map(order => ({ ...order, open: true}) adds a key open with the value true to every order in the array.
To add dynamic keys to a object in javascript we use [].
var x = [{ _id : 1, name: Suzuki}];
x[0]['opened'] = true;
console.log(x);
// [{ _id : 1, name: Suzuki, opened: true}];
Use foreach() to loop through all the orders in the array and add the desired property for each order.
let orders = [{
_id: 1,
name: 'honda',
}, {
_id: 2,
name: 'suzuki',
}, {
_id: 3,
name: 'audi',
}]
orders.forEach(o => o.opened = true)
console.log(orders)
You could add a new property to the objects.
var orders = [{ _id: 1, name: 'honda' }, { _id: 2, name: 'suzuki' }, { _id: 3, name: 'audi' }],
additionalProp = { opened: true };
orders.forEach(o => Object.assign(o, additionalProp));
console.log(orders);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Or map a new array without mutating the original objects.
var orders = [{ _id: 1, name: 'honda' }, { _id: 2, name: 'suzuki' }, { _id: 3, name: 'audi' }],
additionalProp = { opened: true },
result = orders.map(o => Object.assign({}, o, additionalProp));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Get list of duplicate objects in an array of objects

I am trying to get duplicate objects within an array of objects. Let's say the object is like below.
values = [
{ id: 10, name: 'someName1' },
{ id: 10, name: 'someName2' },
{ id: 11, name: 'someName3' },
{ id: 12, name: 'someName4' }
];
Duplicate objects should return like below:
duplicate = [
{ id: 10, name: 'someName1' },
{ id: 10, name: 'someName2' }
];
You can use Array#reduce to make a counter lookup table based on the id key, then use Array#filter to remove any items that appeared only once in the lookup table. Time complexity is O(n).
const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];
const lookup = values.reduce((a, e) => {
a[e.id] = ++a[e.id] || 0;
return a;
}, {});
console.log(values.filter(e => lookup[e.id]));
Let's say you have:
arr = [
{ id:10, name: 'someName1' },
{ id:10, name: 'someName2' },
{ id:11, name: 'someName3' },
{ id:12, name: 'someName4' }
]
So, to get unique items:
unique = arr
.map(e => e['id'])
.map((e, i, final) => final.indexOf(e) === i && i)
.filter(obj=> arr[obj])
.map(e => arr[e]);
Then, result will be
unique = [
{ id:10, name: 'someName1' },
{ id:11, name: 'someName3' },
{ id:12, name: 'someName4' }
]
And, to get duplicate ids:
duplicateIds = arr
.map(e => e['id'])
.map((e, i, final) => final.indexOf(e) !== i && i)
.filter(obj=> arr[obj])
.map(e => arr[e]["id"])
List of IDs will be
duplicateIds = [10]
Thus, to get duplicates objects:
duplicate = arr.filter(obj=> dublicateIds.includes(obj.id));
Now you have it:
duplicate = [
{ id:10, name: 'someName1' },
{ id:10, name: 'someName2' }
]
Thanks https://reactgo.com/removeduplicateobjects/
You haven't clarified whether two objects with different ids, but the same "name" count as a duplicate. I will assume those do not count as a duplicate; in other words, only objects with the same id will count as duplicate.
let ids = {};
let dups = [];
values.forEach((val)=> {
if (ids[val.id]) {
// we have already found this same id
dups.push(val)
} else {
ids[val.id] = true;
}
})
return dups;
With lodash you can solve this with filter and countBy for complexity of O(n):
const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]
const counts = _.countBy(data, 'id')
console.log(_.filter(data, x => counts[x.id] > 1))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
You could do the same with ES6 like so:
const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]
const countBy = (d, id) => d.reduce((r,{id},i,a) => (r[id] = a.filter(x => x.id == id).length, r),{})
const counts = countBy(data, 'id')
console.log(data.filter(x => [x.id] > 1))
You can use an array to store unique elements and use filter on values to only return duplicates.
const unique = []
const duplicates = values.filter(o => {
if(unique.find(i => i.id === o.id && i.name === o.name)) {
return true
}
unique.push(o)
return false;
})
With lodash you can use _.groupBy() to group elements by their id. Than _.filter() out groups that have less than two members, and _.flatten() the results:
const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];
const result = _.flow([
arr => _.groupBy(arr, 'id'), // group elements by id
g => _.filter(g, o => o.length > 1), // remove groups that have less than two members
_.flatten // flatten the results to a single array
])(values);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
An alternative based in #ggorlen solution with new Map() as accumulator (for better performance) and without unary operator ++ (not advised by default in projects with ESLint).
const values = [{ id: 10, name: "someName1" }, { id: 10, name: "someName2" }, { id: 11, name: "someName3" }, { id: 12, name: "someName4" },];
const lookup = values.reduce((a, e) => {
a.set(e.id, (a.get(e.id) ?? 0) + 1);
return a;
}, new Map());
console.log(values.filter(e => lookup.get(e.id) > 1));
Try this
function checkDuplicateInObject(propertyName, inputArray) {
var seenDuplicate = false,
testObject = {};
inputArray.map(function(item) {
var itemPropertyName = item[propertyName];
if (itemPropertyName in testObject) {
testObject[itemPropertyName].duplicate = true;
item.duplicate = true;
seenDuplicate = true;
}
else {
testObject[itemPropertyName] = item;
delete item.duplicate;
}
});
return seenDuplicate;
}
referred from : http://www.competa.com/blog/lets-find-duplicate-property-values-in-an-array-of-objects-in-javascript/

Categories

Resources