How to find a key by value in Javascript? - javascript

I'm new to Javascript and react. I have a react app with the following array and a function to find a key inside the array. I'm providing the search value as parameter and I need to find the key which has the search value. I have three user roles as client, admin and manager. I'm doing the code as follows
Array:
{
client:[{ id:1, name:"Adam" },
{ id:2, name:"Mon" },
{ id:3, name:"Sara" }],
admin:[{ id:4, name:"Jake" },
{ id:5, name:"Jon" },
{ id:6, name:"Sean" }],
manager:[{ id:7, name:"Doe" },
{ id:8, name:"Matt" },
{ id:9, name:"Mark" }]
}
I need to find the user role by given id. This is what I tried.
Component:
roleCheck = (searchId) => {
var roles = this.state.array;
Object.keys(roles).forEach(role => {
Object.keys(role).forEach(user => {
if (user.id === searchId){
return role;
}
});
});
}
The result is always Undefined. How can I solve this?

You're not returning any thing from you function. You can change your coe in following manner
roleCheck = (searchId) => {
var roles = this.state.array;
let output = 'Not found'
Object.keys(roles).forEach(role => {
Object.keys(role).forEach(user => {
if (user.id === searchId){
output = role
}
});
});
return output;
}
Or alternatively You can use find and some
let data = {client:[{ id:1, name:"Adam" },{ id:2, name:"Mon" },{ id:3, name:"Sara" }],admin:[{ id:4, name:"Jake" },{ id:5, name:"Jon" },{ id:6, name:"Sean" }],manager:[{ id:7, name:"Doe" },{ id:8, name:"Matt" },{ id:9, name:"Mark" }]}
let role = (searchId) => {
return Object.keys(data).find(key => {
return data[key].some(({id})=> id === searchId)
})
}
console.log(role(6))
console.log(role(60))

Your return will only return from the function given to forEach and not the checkRole function.
You could instead use a combination of find and some to figure out what role the person with the searchId has:
const data = {
client: [
{ id: 1, name: "Adam" },
{ id: 2, name: "Mon" },
{ id: 3, name: "Sara" }
],
admin: [
{ id: 4, name: "Jake" },
{ id: 5, name: "Jon" },
{ id: 6, name: "Sean" }
],
manager: [
{ id: 7, name: "Doe" },
{ id: 8, name: "Matt" },
{ id: 9, name: "Mark" }
]
};
function roleCheck(searchId) {
return Object.keys(data).find(key => {
return data[key].some(person => person.id === searchId);
});
}
console.log(roleCheck(8));

using the https://underscorejs.org/ library us can do this
var hash = {
foo: 1,
bar: 2
};
(_.invert(hash))[1]; // => 'foo'
you can put this into your loop

Another way to check if a JavaScript Object has a key is using hasOwnProperty method.
let c = {"name": "John", "id": 12};
c.hasOwnProperty("name") // true

Related

Filter 2 arrays to check if parent child

I have first array -
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
And 2nd Array Object -
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
From parent array I want to select all those elements whose id matches with childid from child array.
I tried -
parent.filter(x=>x.id==child.each(y=>y.childid))
But its not working
You can use some() to do it
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
let result = parent.filter(p => child.some(a => a.childid == p.id ))
console.log(result)
using Flatmap and filter ...
let parent = [{
id: 1,
value: "ABC",
},
{
id: 2,
value: "DEF",
},
{
id: 3,
value: "GHI",
},
{
id: 4,
value: "JKL",
},
{
id: 5,
value: "MNO",
},
{
id: 6,
value: "PQR",
},
]
let child = [{
childid: 1,
value: "ABC",
},
{
childid: 2,
value: "DEF",
},
{
childid: 10,
value: "GHI",
},
]
const res = parent.flatMap(x => child.filter(y => y.childid === x.id))
console.log(res)
This would work
parent.filter(p => child.some(c => c.childid === p.id))
Wat happens is
For each element in parent array, find the corresponding element in the child array
If it exists the filter will see it as truthy and keep the parent element, if not it will be falsy and filter wil discard it
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
const filterResult = parent.filter(x => child.some(y => y.childid == x.id))
You can use a reduce function along with a forEach to loop through the child elements and compare against the parent.
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
});
return acc;
}, []);
console.log(result); // [{"id":1,"value":"ABC"},{"id":2,"value":"DEF"}]
const parents = [{
id: 1,
value: 'ABC',
},
{
id: 2,
value: 'DEF',
},
{
id: 3,
value: 'GHI',
},
{
id: 4,
value: 'JKL',
},
{
id: 5,
value: 'MNO',
},
{
id: 6,
value: 'PQR',
},
];
const children = [{
childid: 1,
value: 'ABC',
},
{
childid: 2,
value: 'DEF',
},
{
childid: 10,
value: 'GHI',
},
];
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
return acc;
});
return acc;
}, []);
console.log(result);
MDN Reduce

Return last value with recursion - Javascript

Hi all I have following data:
const section = {
fileds: [
{ id: "some Id-1", type: "user-1" },
{
child: [
{ id: "some Id-2", type: "user-2" },
{ fileds: [{ id: "kxf5", status: "pending" }] },
{ fileds: [{ id: "ed5t", status: "done" }] }
]
},
{
child: [
{ id: "some Id-3", type: "teacher" },
{ fileds: [{ id: "ccfr", status: null }] },
{ fileds: [{ id: "kdpt8", status: "inProgress" }] }
]
}
]
};
and following code:
const getLastIds = (arr) =>
arr.flatMap((obj) => {
const arrayArrs = Object.values(obj).filter((v) => Array.isArray(v));
const arrayVals = Object.entries(obj)
.filter(([k, v]) => typeof v === "string" && k === "id")
.map(([k, v]) => v);
return [...arrayVals, ...arrayArrs.flatMap((arr) => getLastIds(arr))];
});
console.log(getLastIds(section.fileds));
// output is (7) ["some Id-1", "some Id-2", "kxf5", "ed5t", "some Id-3", "ccfr", "kdpt8"]
My code doing following, it printing in new array all ids.
It's working but I don't need all ids.
I need to return only last id in array and I should use recursion.
The output should be
(4) [" "kxf5", "ed5t", "ccfr", "kdpt8"]
P.S. here is my code in codesandbox
Is there a way to solve this problem with recursion? Please help to fix this.
You can do it with reduce.
function getLastIds (value) {
return value.reduce((prev, cur) => {
if (cur.id) {
return [ ...prev, cur.id ];
} else {
let key = ('child' in cur) ? 'child' : 'fileds';
return [ ...prev, ...getLastIds (cur[key]) ]
}
}, []);
}
You could check if a certain key exists and take this property for mapping id if status exists.
const
getValues = data => {
const array = Object.values(data).find(Array.isArray);
return array
? array.flatMap(getValues)
: 'status' in data ? data.id : [];
},
section = { fileds: [{ id: "some Id-1", type: "user-1" }, { child: [{ id: "some Id-2", type: "user-2" }, { fileds: [{ id: "kxf5", status: "pending" }] }, { fileds: [{ id: "ed5t", status: "done" }] }] }, { child: [{ id: "some Id-3", type: "teacher" }, { fileds: [{ id: "ccfr", status: null }] }, { fileds: [{ id: "kdpt8", status: "inProgress" }] }] }] },
result = getValues(section);
console.log(result);

Filter array inside array

I have the array as below
test_list = [
{
id: 1,
test_name: 'Test 1',
members: [
{
user_id: 3
},
{
user_id: 4
}
],
},
{
id: 2,
test_name: 'Test 2',
members: [
{
user_id: 4
},
{
user_id: 5
},
],
},
{
id: 3,
test_name: 'Test 2',
members: [
{
user_id: 8
},
{
user_id: 10
},
],
}
]
I want to filter the test for specific user_id, example if user_id = 4 I would like to have this result
{
id: 1,
...
},
{
id: 2,
...
},
I have tried with this but it only return the member
test_list.filter(function(item) {
item.members.filter(function(member) {
if(member.user_id === 4) {
return item;
}
});
})
Would anyone please help me in this case?
Check if .some of the objects in the members array have the user_id you're looking for:
test_list = [{
id: 1,
test_name: 'Test 1',
members: [{
user_id: 3
},
{
user_id: 4
}
],
},
{
id: 2,
test_name: 'Test 2',
members: [{
user_id: 4
},
{
user_id: 5
},
],
},
{
id: 3,
test_name: 'Test 2',
members: [{
user_id: 8
}]
}
];
const filtered = test_list.filter(
({ members }) => members.some(
({ user_id }) => user_id === 4
)
);
console.log(filtered);
You could use .reduce() and .filter() method of array to achieve required result.
Please check below working code snippet:
const arr = [{"id":1,"test_name":"Test 1","members":[{"user_id":3},{"user_id":4}]},{"id":2,"test_name":"Test 2","members":[{"user_id":4},{"user_id":5}]},{"id":3,"test_name":"Test 2","members":[{"user_id":8}]}];
const data = arr.reduce((r,{ members,...rest }) => {
let rec = members.filter(o => o.user_id === 4)
if(rec.length){
rest.members = rec;
r.push(rest);
}
return r;
},[]);
console.log(data);
Hope this works.
var members = item.members;
var filterById =members.filter((item1)=>{
return (item1.user_id===4)
});
return filterById.length > 0;
});
console.log(test_List_by_id)```

What is an alternative way to update an array of objects?

I have a array of objects. I want to update an object using id.
I am able to do using the map function. Is there an alternative way or more efficient way to update the array?
Here is my code:
https://stackblitz.com/edit/js-xgfwdw?file=index.js
var id = 3
var obj = {
name: "test"
}
let arr = [{
name: "dd",
id: 1
}, {
name: "dzxcd",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
function getUpdated(obj, id) {
var item = [...arr];
const t = item.map((i) => {
if(i.id==id){
return {
...obj,
id
}
}else {
return i;
}
})
return t
}
console.log(getUpdated(obj,id))
The expected output is correct but I want to achieve the same functionality using an alternative way.
[{
name: "dd",
id: 1
}, {
name: "test",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
you are in the correct way, basically the bad thing that you are doing is creating new arrays [...arr], when map already gives you a new array.
other things to use, may be the ternary operator and return directly the result of the map function
check here the improvedGetUpdate:
var id = 3;
var obj = {
name: "test"
};
let arr = [{
name: "dd",
id: 1
}, {
name: "dzxcd",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
function getUpdated(obj, id) {
var item = [...arr];
const t = item.map((i) => {
if (i.id == id) {
return {
...obj,
id
}
} else {
return i;
}
})
return t
}
improvedGetUpdate = (obj, id) => arr.map(i => {
return i.id !== id ? i : {
...obj,
id
}
})
console.log(getUpdated(obj, id))
console.log(improvedGetUpdate(obj, id))
var id = 3
var obj = {
name: "test"
}
let arr = [{
name: "dd",
id: 1
}, {
name: "dzxcd",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
const result = arr.map((el) => el.id === id ? {...obj, id} : el)
console.log(result);
Use splice method which can be used to update the array too:
var obj = {
id: 3,
name: "test"
}
let arr = [{
name: "dd",
id: 1
}, {
name: "dzxcd",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
arr.splice(arr.findIndex(({id}) => id === obj.id), 0, obj);
console.log(arr);
#quirimmo suggested short code.
I suggest fast code.
var id = 3;
var obj = {
id: 3,
name: "test"
}
let arr = [{
name: "dd",
id: 1
}, {
name: "dzxcd",
id: 3
}, {
name: "nav",
id: 5
}, {
name: "hhh",
id: 4
}]
var arr2 = [...arr];
console.time('⏱');
arr.splice(arr.findIndex(({id}) => id === obj.id), 0, obj);
console.timeEnd('⏱');
console.time('⏱');
for (let item of arr2) {
if (item.id === id) {
item.name = obj.name;
break;
}
}
console.timeEnd('⏱');
console.log(arr2);

Get objects having id in 1st array as same as id in objects of other array in java script

I have 2 arrays of objects.
They are
array1 = [{
id:2,
name:"person2"
},{
id:3,
name:"person3"
},
{
id:4,
name:"person4"
},
{
id:5,
name:"person5"
},
];
array2 = [
{
empId:2,
isdeleted:false
},
{
empId:4,
isdeleted:false
},
{
empId:3,
isdeleted:true
}];
I need the object from array1 whose id matches with empId of array2 and having isdeleted false. Thanks in advance.
You can use filter and some like this:
let array1 = [{
id: 2,
name: "person2"
}, {
id: 3,
name: "person3"
},
{
id: 4,
name: "person4"
},
{
id: 5,
name: "person5"
},
];
let array2 = [{
empId: 2,
isdeleted: false
},
{
empId: 4,
isdeleted: false
},
{
empId: 3,
isdeleted: true
}
];
let filteredArray = array1.filter(a => array2.some(b => b.empId === a.id && !b.isdeleted));
console.log(filteredArray);
Try
let result = [];
array1.forEach(function(element1){
array2.forEach(function(element2){
if (element1.id === element2.empId && !element2.isdeleted){
result.push(element);
}
});
});
console.log(result);
You can use Array.filter() together with find() to find the object with that condition in array2:
var array1 = [{
id: 2,
name: "person2"
}, {
id: 3,
name: "person3"
},
{
id: 4,
name: "person4"
},
{
id: 5,
name: "person5"
},
];
var array2 = [{
empId: 2,
isdeleted: false
},
{
empId: 4,
isdeleted: false
},
{
empId: 3,
isdeleted: true
}
];
var res = array1.filter((obj1)=>{
var exist = array2.find((obj2)=> (obj1.id == obj2.empId && !obj2.isdeleted));
return exist;
});
console.log(res);
You could try something like this:
let array1 = [
{ id:2, name:"person2"},
{ id:3, name:"person3"},
{ id:4, name:"person4"},
{ id:5, name:"person5"}
];
let array2 = [
{ empId:2, isdeleted:false},
{ empId:4, isdeleted:false},
{ empId:3, isdeleted:true}
];
let result = array1.reduce((output, item) => {
if (array2.find((item2) => !item2.isdeleted && item.id === item2.empId)) output.push(item);
return output;
}, []);
console.log(result);

Categories

Resources