Get id that is not present in object array - javascript

I have one array and one object that contains array of ids (permission objects).
now i want to get the ids that are not present in the object can anyone help me with the logic?
id: [2,3,4]
object = [0:
Permission: {id: 2},
1: Permission: {id: 3}
]
result: [4]

Use filter(). Example:
var id = [2,3,4];
var object = [
{id: 2},
{id: 3}
];
objectIds = object.map(myObj => myObj.id);
idNotIn = id.filter(myId => !objectIds.includes(myId));
console.log('objectIds: '+ objectIds);
console.log('idNotIn: '+ idNotIn);
Or in a single line of code:
idNotIn = id.filter(myId => !object.map(myObj => myObj.id).includes(myId));

Related

how to get id based on value of objects and set into another object - javascript

There are two array of objects and i want to filter two values by iterating differently to get two different id.
Here is the example
1st array : list_of_products: [ { text: "Shoes", value: 1},{text:"Clothing", value: 2},{text:"Foods", value: 3}]
2nd Array: list_of_names: [{ text: "jim" , value: 1},{text:"Sim", value: 2},{text:"Tim",value:3}]
Now, i want to get the ids by filtering out two arrays based on names like this
product_name: "Clothing", person_name:"Tim"
Then i want to store the ids like this
const newIds = { product_id: 2,name_id: 3}
This i have tried:
const newProduct_name = list_of_products.find(name => name.text === product_name);
const newName = list_of_names.find(name => name.text === person_name);
storing it into new object like this
const values = {product_id: newProduct_name.value ,name_id: newName.value}
How to do this by minimal use of variables and faster execution?
Creating Maps or objects using the lookup values as keys lets you iterate each of your source arrays once and then have o(1) searches rather than using find() to iterate each array many times
const products= [ { text: "Shoes", value: 1},{text:"Clothing", value: 2},{text:"Foods", value: 3}],
names= [{ text: "jim" , value: 1},{text:"Sim", value: 2},{text:"Tim",value:3}];
const createMap = (arr) => new Map(arr.map(o => [o.text, o.value])),
prodMap = createMap(products),
namesMap = createMap(names);
const data = [{
product_name: "Clothing",
person_name: "Tim"
}];
const res = data.map(o => {
return {
product_id: prodMap.get(o.product_name),
name_id: namesMap.get(o.person_name)
};
})
console.log(res)

Destructuring data from a multidimensional array

I have an array of nested objects, like so:
const objArr = [{obj, obj, objIWant}, {obj, obj, objIWant}, {obj, obj, objIWant}]
Is there a way to get to objIWant without having to loop twice like:
ObjArr.map((obj)=> obj.map(({ objIWant }) => myFunc(objIWant)))
I was hoping I could perhaps leverage destructuring but trying something like [{ objIWant }] = objArr only returns the first objIWant. Am I missing something about destructuring syntax that would allow for this? Many thanks!
No - the only way to do it is with nested map calls.
ObjArr.map(obj => obj.map(({ objIWant }) => myFunc(objIWant));
If you are able to do so, you could change myFunc:
myFunc({ objIWant }) {...}
And then change your code to do this:
ObjArr.map(obj => obj.map(myFunc));
But there's no way using destructuring to do what you're asking.
Destructuring will not make it look cleaner. This is the only way to destructure the properties you want. Using the map function as you are now is a cleaner way of doing it.
const objArr = [{obj:1, obj2:2, objIWant:3}, {obj:4, obj2:5, objIWant:6}, {obj:7, obj2:8, objIWant:9}];
const [{objIWant}, {objIWant:test2}, {objIWant:test3}] = objArr;
window.console.log(objIWant);
window.console.log(test2);
window.console.log(test3);
Not sure if your structure is expected to return an array of objects - or an array of values from each object. But the solution would be the same - use .map() on the original array to return the values (or objects) that you want.
const objArr = [
{id: 1, name: 'first item', value: 1},
{id: 2, name: 'second item', value: 2},
{id: 3, name: 'third item', value: 3}
];
const objIWant = 'value';
const result = objArr.map(item => item[objIWant]);
console.log(result);
// expected output: Array ["1", "2", "3"]
if its a nested object then same deal - use .map() on the original array to construct a new array of the desired objects.
const objArr = [
{"obj": {id: 1}, "obj": { id:1 } , "objIWant": { id:1 }},
{"obj": {id: 1}, "obj": { id:1 } , "objIWant": { id:2 }},
{"obj": {id: 1}, "obj": { id:1 } , "objIWant": { id:3 }}
];
const objIWant = 'objIWant';
const result = objArr.map(item => item[objIWant]);
console.log(result);
// expected output: Array [{"id": 1},{"id": 2},{"id": 3}]

compare two arrays based on a id and return a new array based on values

Trying to loop over two arrays and finding the codes for each, I might be missing some part. I need to construct a new array with this values, each id can be multiple times in the arrayB. Based on id in first array we have to match the id in a second array (arrayA) and get code
let arrayA=[
{"breadcrumb":{id: "abdc4051"}, type:"details"},
{"breadcrumb":{id: "abdc4052"}, type:"details"},
let arrayB=[
{"breadcrumb": {id: "abdc4051",code: "mike", length:"short"}},
{"breadcrumb": {id: "abdc4051", code: "pohan", length:"long"}}, {"breadcrumb": {id: "abdc4052", code: "junior", length:"short"}}]
let arrayC = [];
// output expected
[{"id":"abdc4051", shortLength: "mike", longLength:"pohan"}, {"id":"abdc4052", shortLength: "Junior", longLength:"-"}]
// tried this
function isBiggerThan10(element, index, array) {
return element > 10;
}
arrayA.forEach(function(element){
arrayC.push({
id:element.id,
firstName:(arrayB.find(
e => e.attributes.code==="mike")).breadCrumbs.shortLength,
lastName:(arrayB.find(
e => e.code==="pohan")).breadCrumbs.longlength
})
});
console.log(arrayC);
Here's one solution using the built in array methods. The steps are:
For each item in arrayA, perform the following:
Find all items in arrayB that have the same ID (using .filter).
Combine all those results into a single object, using default "-" for first and last name if not present (using .reduce).
Put that into the results array (handled by using .map on arrayA in the first place).
let arrayA = [
{"breadcrumb":{id: "abdc4051"}, type:"details"},
{"breadcrumb":{id: "abdc4052"}, type:"details"},
]
let arrayB = [
{"breadcrumb": {id: "abdc4051", firstName: "mike"}},
{"breadcrumb": {id: "abdc4051", lastName: "pohan"}},
{"breadcrumb": {id: "abdc4052", firstName: "junior"}},
]
// output expected
// [
// {"id":"abdc4051", firstName: "mike", lastName:"pohan"},
// {"id":"abdc4052", firstName: "Junior", lastName:"-"},
// ]
const result = arrayA.map(itemA => {
return arrayB
.filter(itemB => itemB.breadcrumb.id === itemA.breadcrumb.id)
.reduce((combo, item) => ({...combo, ...item.breadcrumb}), {firstName: "-", lastName: "-"})
});
console.log(result);
EDIT: Per edited question, you can modify the reduce function to see if the combo has firstCode set or not. If it does, then put the next code under the key lastCode, otherwise keep it as firstCode. This will base the first/last code on the order they appear in arrayB:
let arrayA = [
{"breadcrumb":{id: "abdc4051"}, type:"details"},
{"breadcrumb":{id: "abdc4052"}, type:"details"},
]
let arrayB = [
{"breadcrumb": {id: "abdc4051", code: "mike"}},
{"breadcrumb": {id: "abdc4051", code: "pohan"}},
{"breadcrumb": {id: "abdc4052", code: "junior"}},
]
// output expected
// [
// {"id":"abdc4051", firstCode: "mike", lastCode:"pohan"},
// {"id":"abdc4052", firstCode: "Junior", lastCode:"-"},
// ]
const result = arrayA.map(itemA => {
return arrayB
.filter(itemB => itemB.breadcrumb.id === itemA.breadcrumb.id)
.reduce((combo, item) => ({...combo, [combo.firstCode === "-" ? "firstCode" : "lastCode"]: item.breadcrumb.code, id: itemA.breadcrumb.id}), {firstCode: "-", lastCode: "-"})
});
console.log(result);
EDIT 2: Per second edit, you can again modify the reduce to suit your needs:
let arrayA = [
{"breadcrumb":{id: "abdc4051"}, type:"details"},
{"breadcrumb":{id: "abdc4052"}, type:"details"},
]
let arrayB = [
{"breadcrumb": {id: "abdc4051", code: "mike", length: "short"}},
{"breadcrumb": {id: "abdc4051", code: "pohan", length: "long"}},
{"breadcrumb": {id: "abdc4052", code: "junior", length: "short"}},
]
// output expected
// [
// {"id":"abdc4051", shortLength: "mike", longLength:"pohan"},
// {"id":"abdc4052", shortLength: "junior", longLength:"-"},
// ]
const result = arrayA.map(itemA => {
return arrayB
.filter(itemB => itemB.breadcrumb.id === itemA.breadcrumb.id)
.reduce((combo, item) => ({...combo, [item.breadcrumb.length + "Length"]: item.breadcrumb.code, id: itemA.breadcrumb.id}), {shortLength: "-", longLength: "-"})
});
console.log(result);
Start a chain with arrayB. Use _.map() to get the content of breadcrumb, _.groupBy() by id. Use _.pick() with the ids of arrayA to get the groups you want. Map each group to required form using _.transform():
const arrayA=[{"breadcrumb":{"id":"abdc4051"},"type":"details"},{"breadcrumb":{"id":"abdc4052"},"type":"details"}];
const arrayB=[{"breadcrumb":{"id":"abdc4051","code":"mike","length":"short"}},{"breadcrumb":{"id":"abdc4051","code":"pohan","length":"long"}},{"breadcrumb":{"id":"abdc4052","code":"junior","length":"short"}}];
const result = _(arrayB)
.map('breadcrumb') // unwrap breadcrumb
.groupBy('id')
.pick(arrayA.map((o) => _.get(o, 'breadcrumb.id'))) // get all groups that match arrayA ids
.map((g, key) => _.transform(g, (acc, v) => { // transform each group to the requested form
acc[`${v.length}Length`] = v.code;
}, { key, shortLength: '-', longLength: '-' }))
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

ES6 filter - how to return an object instead of an array?

I have bunch of array of object, I want to get particular object using filter, but I got array using below code.
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}]
const x = target.filter(o => o.id === 1)
console.log(x)
As said in the comments, filter won't allow you to get a particular object from an array - it just returns another array which elements satisfy the given predicate. What you actually need is Array.prototype.find(). Quoting the doc:
The find() method returns the value of the first element in the array
that satisfies the provided testing function. Otherwise undefined is
returned.
So your code looks like this:
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}];
const x = target.find(o => o.id === 1);
console.log(x); // {name: "abc", id: 1}
array.filter always return array. But you can try this-
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}]
let obj = {}
const x = target.filter( (o, index) => {
if(o.id === 1)
obj = target[index]
})
console.log(obj)
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
Array.prototype.filter will return array containing elements from original array that passed test function.
If you are sure that id's are unique simply do x[0] to get result.
It's very easy just get first item in retrned as:
const target = [{name: 'abc', id: 1}, {name: 'def', id: 2}]
const x = target.filter(o => o.id === 1)
console.log(x[0])

map array of object by property

I have this (says it's Object A)
[{grade:1},{grade:2},{grade:3}] till 100th.
how to map this existing data (says its name is object B) into them?
[
{grade:1,name:'alice',address:{poscode:123},tel:324}
{grade:5,name:'wonder',address:{poscode:123},tel:1234223},
{grade:90,name:'james',address:{poscode:234},tel:324}]
]
Says grade 50, it doesn't match any of Object B, the final result should also have the name and address property, assign the value null to them to make the array consistent. I issue is what if there's other property in Object B if I loop using Object A?
If I understand the issue correctly, you can use Object A as your map source, then use Object.assign to copy individual properties from Object B as well as adding in some defaults:
const objA = [{grade:1},{grade:2},{grade:3}];
const objB = [
{grade:1,name:'alice',address:{poscode:123},tel:324},
{grade:5,name:'wonder',address:{poscode:123},tel:1234223},
{grade:90,name:'james',address:{poscode:234},tel:324}
];
const objC = objA.map(rootObject => Object.assign(
// A new object with some defaults
{ name: null, address: null, tel: null },
// The source object from objA
rootObject,
// The data object from objB, if any
objB.find(detail => detail.grade === rootObject.grade)
)
);
console.log(objC);
You can achieve that using convenient Array methods. See snippet below:
const a = [
{grade: 1},
{grade: 2},
{grade: 3},
{grade: 4},
{grade: 5},
{grade: 90},
{grade: 100}
];
const b = [
{grade:1,name:'alice',address:{poscode:123},tel:324},
{grade:5,name:'wonder',address:{poscode:123},tel:1234223},
{grade:90,name:'james',address:{poscode:234},tel:324}
];
let result = a.map(aItem => {
let match = b.find( bItem => aItem.grade === bItem.grade );
if(!match){
return Object.assign({}, aItem, { name: null, address: {}, tel: null });
} else {
return match;
}
});
console.log(result);

Categories

Resources