I had a lists of duplicate array of String and array of object. I want to find the property into one particular object of array uniquely without duplication of array object.
If can done in lodash library, it would be awesome.
const arr1 = ['test#email', 'test2#email']
const arr2 = [{ id: 1, email: 'test#email' }]
Expected result
['test2#email']
this is what I done so far
By turning arr1 into object frist so I can compare with arr2
const emailLists = _.map(arr, function (item) {
console.log(item)
return { email: item }
})
then merge them to together and used uniq to remove duplicates
const merge = _.unionBy(array1, array2, 'email')
const result _.uniq(merge, 'email');
I think it still not a good process and not clean
You can do it without lodash
const arr1 = ['test#email', 'test2#email']
const arr2 = [{ id: 1, email: 'test#email' }]
const emailToDelete = arr2.map(a => a.email)
const result = arr1.filter(e => !emailToDelete.includes(e))
console.log(result)
You can use lodash chain to solve that:
const result = _([...arr1, ...arr2.map(i => i.email)]) // ['test#email', 'test2#email', 'test#email']
.countBy() // { test#email: 2, test2#email: 1 }
.pickBy(count => count === 1) // { test2#email: 1 }
.keys() // ['test2#email']
.value();
You can use filter on the first array and check that an email address matches with some of your objects in the second array. So even if it matches with multiple objects, the matching email will only be in the output once.
I want to find the property into one particular object of array uniquely without duplication of array object
So then your expected output is wrong, as you provide an email that is not found in the object array. I guess that was a typo in your question.
const arr1 = ['test#email', 'test2#email']
const arr2 = [{ id: 1, email: 'test#email' }]
const result = arr1.filter(search => arr2.some(({email}) => email == search));
console.log(result);
Related
Suppose there is an array like this:
const a = [ {p:1}, {p:2}, {p:3} ];
Is it possible to destructure this array in order to obtain p = [1, 2, 3] ?
Because this does not work :
const [ ...{ p } ] = a; // no error, same as const p = a.p;
// p = undefined;
Edit
In response to all the answers saying that I need to use Array.prototype.map, I am aware of this. I was simply wondering if there was a way to map during the destructuring process, and the answer is : no, I need to destructure the array itself, then use map as a separate step.
For example:
const data = {
id: 123,
name: 'John',
attributes: [{ id:300, label:'attrA' }, { id:301, label:'attrB' }]
};
function format(data) {
const { id, name, attributes } = data;
const attr = attributes.map(({ label }) => label);
return { id, name, attr };
}
console.log( format(data) };
// { id:123, name:'John', attr:['attrA', 'attrB'] }
I was simply wondering if there was a way, directly during destructuring, without using map (and, respectfully, without the bloated lodash library), to retrive all label properties into an array of strings.
Honestly I think that what you are looking for doesn't exist, normally you would map the array to create a new array using values from properties. In this specific case it would be like this
const p = a.map(element => element.p)
Of course, there are some packages that have many utilities to help, like Lodash's map function with the 'property' iteratee
you can destructure the first item like this :
const [{ p }] = a;
but for getting all values you need to use .map
and the simplest way might be this :
const val = a.map(({p}) => p)
Here's a generalized solution that groups all properties into arrays, letting you destructure any property:
const group = (array) => array.reduce((acc,obj) => {
for(let [key,val] of Object.entries(obj)){
acc[key] ||= [];
acc[key].push(val)
}
return acc
}, {})
const ar = [ {p:1}, {p:2}, {p:3} ];
const {p} = group(ar)
console.log(p)
const ar2 = [{a:2,b:1},{a:5,b:4}, {c:1}]
const {a,b,c} = group(ar2)
console.log(a,b,c)
Hello I'm trying to create an object that includes under the same property name a bunch of array values,
This what I'm trying
const quiz = [
{question: 'Who is the main character of DBZ',
options: ['Vegetta','Gohan','Goku']}
]
const newObj = {
options: []
}
quiz.forEach((item)=>{
item.options.forEach((item, index)=>{
newObj.options[`name${index}`] = item
})
})
expected value =
newObj = {
options: [{name: 'Vegetta'},{name:'Gohan'},{name:'Goku'}]
}
actual value received =
newObj = {
{ options: [ name0: 'Vegetta', name1: 'Gohan', name2: 'Goku' ] }}
Thanks in advance!
As you've noticed, newObj.options[`name${index}`] = item creates a new key on your options array, and sets that to item. You instead want to push an object of the form {name: item} into your array. There are a few ways you could go about this, one way is to use .push() like so:
quiz.forEach((item)=>{
item.options.forEach((item)=>{
newObj.options.push({name: item});
})
});
while not as common, you can also use set the current index of options, which is slightly different to the above example, as it will maintain the same index, which can be important if quiz is a sparse array that you want to keep the same indexing of on options:
quiz.forEach((item)=>{
item.options.forEach((item, index)=>{
newObj.options[index] = {name: item};
})
});
Example of the difference:
const arr = [1, 2,,,5]; // sparse array
const pushRes = [];
const indxRes = [];
arr.forEach(n => pushRes.push(n));
arr.forEach((n, i) => indxRes[i] = n);
console.log("Push result", pushRes);
console.log("Index result", indxRes);
For a different approach, you also have the option of using something like .flatMap() and .map() to create your options array, which you can use to create newObj:
const quiz = [
{question: 'Who is the main character of DBZ',
options: ['Vegetta','Gohan','Goku']}
];
const options = quiz.flatMap(({options}) => options.map(name => ({name})));
const newObj = {options};
console.log(newObj);
Hello so i have array of objects something like this
const old = [{id: 1, name: 'Random'}, {id: 2, name: 'Random2'}]
also i have array
const wantedField = ['id']
So looking this result, i need values only for certain key
const finally = [[1],[2]]
I have tried something like this but not luck. End result should be array of arrays with just certain values.
old.map((obj, value) => {
const key = Object.keys(obj)[value]
if(wantedField.includes(const)) {
const newArray = []
const key = Object.keys(obj)[value]
newArray.push(obj[key])
return [newArray]
}
})
So this return [newArray] is wrong should return multiple values not just one. Please help regards.
This is a one-liner, with two nested maps. One to iterate over the input array, and another to iterate over the wanted field(s):
const old = [{id: 1, name: 'Random'}, {id: 2, name: 'Random2'}];
const wantedField = ['id'];
const result = old.map(o => wantedField.map(k => o[k]));
console.log(result);
I'm creating an empty array and fill it with object.
export const model = [
{isMine: false},
]
const newArr = Array(25);
newArr.fill(model);
newArr.forEach((item) => {
console.log(item);
})
This logs out all objects with the array. But I don't know how to log out the isMine property... I always get undefined
I hope this is what you need. If you spread (...) the model it will get stored as objects. But if you don't spread it will be stored as an array inside an array which contain an object
const model = [
{isMine: false},
]
const newArr = Array(25).fill(...model);
newArr.forEach((item) => {
console.log(item.isMine);
})
I hope this helps, you need to access array inside array
const model = [
{isMine: false},
];
console.log(model[0].isMine);
const newArr = Array(25);
newArr.fill(model);
console.log(newArr);
newArr.forEach(x => x.forEach(y => console.log(y.isMine)));
newArr is a 2 dimensional array, since model is an array.
So to access the property isMine in your forEach loop you'd do:
newArr.forEach((item) => {
// item is an array, so get the value at the first index
console.log(item[0].isMine);
})
Okay, so I am trying to create a function that allows you to input an array of Objects and it will return an array that removed any duplicate objects that reference the same object in memory. There can be objects with the same properties, but they must be different in-memory objects. I know that objects are stored by reference in JS and this is what I have so far:
const unique = array => {
let set = new Set();
return array.map((v, index) => {
if(set.has(v.id)) {
return false
} else {
set.add(v.id);
return index;
}
}).filter(e=>e).map(e=>array[e]);
}
Any advice is appreciated, I am trying to make this with a very efficient Big-O. Cheers!
EDIT: So many awesome responses. Right now when I run the script with arbitrary object properties (similar to the answers) and I get an empty array. I am still trying to wrap my head around filtering everything out but on for objects that are referenced in memory. I am not positive how JS handles objects with the same exact key/values. Thanks again!
Simple Set will do the trick
let a = {'a':1}
let b = {'a': 1,'b': 2, }
let c = {'a':1}
let arr = [a,b,c,a,a,b,b,c];
function filterSameMemoryObject(input){
return new Set([...input])
}
console.log(...filterSameMemoryObject(arr))
I don't think you need so much of code as you're just comparing memory references you can use === --> equality and sameness .
let a = {'a':1}
console.log(a === a ) // return true for same reference
console.log( {} === {}) // return false for not same reference
I don't see a good reason to do this map-filter-map combination. You can use only filter right away:
const unique = array => {
const set = new Set();
return array.filter(v => {
if (set.has(v.id)) {
return false
} else {
set.add(v.id);
return true;
}
});
};
Also if your array contains the objects that you want to compare by reference, not by their .id, you don't even need to the filtering yourself. You could just write:
const unique = array => Array.from(new Set(array));
The idea of using a Set is nice, but a Map will work even better as then you can do it all in the constructor callback:
const unique = array => [...new Map(array.map(v => [v.id, v])).values()]
// Demo:
var data = [
{ id: 1, name: "obj1" },
{ id: 3, name: "obj3" },
{ id: 1, name: "obj1" }, // dupe
{ id: 2, name: "obj2" },
{ id: 3, name: "obj3" }, // another dupe
];
console.log(unique(data));
Addendum
You speak of items that reference the same object in memory. Such a thing does not happen when your array is initialised as a plain literal, but if you assign the same object to several array entries, then you get duplicate references, like so:
const obj = { id: 1, name: "" };
const data = [obj, obj];
This is not the same thing as:
const data = [{ id: 1, name: "" }, { id: 1, name: "" }];
In the second version you have two different references in your array.
I have assumed that you want to "catch" such duplicates as well. If you only consider duplicate what is presented in the first version (shared references), then this was asked before.