I have two array of objects,arr1 and arr2
if taskId and id same then retreive from arr1
How to check based on property from arr1 and arr2 in javascript
var arr1= [
{"name":"refresh task","memberIds":[981],"dueOn":"2022-08-30","taskId":19},
{"name":"ref one","memberIds":[981,982],"dueOn":"2022-08-25","taskId":null}
]
var arr2 =[
{
"country": "IN",
"tasks": [
{id: 19, "name": "abc" },
{id: 20, "name": "xyz" }
]
}
]
I tried
var result = arr1.filter(e=>e.taskId===(arr2.map(i=>i.tasks.map(t=>t.id))
Expected Output
[
{"name":"refresh task","memberIds":[981],"dueOn":"2022-08-30","taskId":19}
]
Using Set, Array#flatMap, and [Array#map][3], get the list of task ids in arr2``
Using Array#filter, and Set#has, return the resulting array where taskId is in the above set
const
arr1= [
{"name":"refresh task", "memberIds":[981], "dueOn":"2022-08-30", "taskId":19},
{"name":"ref one", "memberIds":[981,982], "dueOn":"2022-08-25", "taskId":null}
],
arr2 =[
{
"country": "IN",
"tasks": [ {"id": 19, "name": "abc"}, {"id": 20, "name": "xyz"} ]
}
];
const taskIdSet = new Set(
arr2.flatMap(({ tasks = [] }) => tasks.map(({ id }) => id))
);
const result = arr1.filter(({ taskId }) => taskIdSet.has(taskId));
console.log(result);
EDIT:
To get "I have two arrays of objects, arr1, and arr2 if taskId and id not same then retrieve from arr2":
const
arr1= [
{"name":"refresh task", "memberIds":[981], "dueOn":"2022-08-30", "taskId":19},
{"name":"ref one", "memberIds":[981,982], "dueOn":"2022-08-25", "taskId":null}
],
arr2 =[
{
"country": "IN",
"tasks": [ {"id": 19, "name": "abc"}, {"id": 20, "name": "xyz"} ]
}
];
const taskIdSet = arr1.reduce((taskIdSet, { taskId }) => {
if(taskId !== null) { taskIdSet.add(taskId); }
return taskIdSet;
}, new Set);
const result = arr2
.flatMap(({ tasks = [] }) => tasks)
.filter(({ id }) => !taskIdSet.has(id));
console.log(result);
This works too:
var result = arr1.filter(e=>{
for(let obj of arr2){
for(let task of obj.tasks){
return e.taskId === task.id;
}
}
})
Related
I struggled with a problem for more than an hour, how can I turn this nested array
[
[
{
"name": "1",
}
],
[
{
"name": "a",
},
{
"name": "b",
}
]
]
into this:
[
{
name: '1',
},
{
id: 'a-b',
grouped: [
{
name: 'a',
},
{
name: 'b',
},
],
},
]
I don't mind using lodash. Not sure should I flatten it before anything else would make things easier.
You could use map() to form the id and grab the parts needed to reconstruct the new array.
const data = [
[{
"name": "1",
}],
[{
"name": "a",
},
{
"name": "b",
}
]
];
const result = [
...data[0],
{
id: data[1].map(r => r.name).join("-"),
grouped: data[1]
}
];
console.log(result);
to flatten the array is a good start. That will remove the superfluous dimension from the rawArray:
const newArray = array.flat()
Now you have an array with three simple objects. The first will remain unchanged. The second element of your finalArray needs to be an object, so let's create it:
const obj = {}
the obj has two keys: id and grouped. The property of id is a string that we can create like this:
obj.id = newArray[1].name + "-" + newArray[2].name
the property of grouped remains the same:
obj.grouped = array[1]
so the finalArray is now straight forward:
const finalArray = [ newArray[0], obj ]
Put it all together in a function:
const rawArray1 = [
[
{
"name": "1a",
}
],
[
{
"name": "a",
},
{
"name": "b",
}
]
]
const rawArray2 = [
[
{
"name": "1b",
}
],
[
{
"name": "aa",
},
{
"name": "bb",
}
]
]
transformArray( rawArray1 )
transformArray( rawArray2 )
function transformArray( array ){
const newArray = array.flat()
const obj = {}
obj.id = newArray[1].name + "-" + newArray[2].name
obj.grouped = array[1]
const finalArray = [ newArray[0], obj ]
console.log(finalArray)
return finalArray
}
I managed to solve it using simple forEach, push, and flat. It's more simple than I thought, I was confused and stuck with map and reduce.
let result = [];
[
[{
"name": "1",
}],
[{
"name": "a",
},
{
"name": "b",
}
]
].forEach((val) => {
const [{
name
}] = val
if (val.length === 1) {
result.push({
name,
})
} else if (val.length > 1) {
result.push({
id: val.map(val2 => val2.name).join('-'),
grouped: val
})
}
})
console.log(result.flat())
const array1 = [
[{ name: "1" }],
[
{ name: "a" },
{ name: "b" }
]
]
const array2 = [
[{ name: "2" }],
[
{ name: "aa" },
{ name: "bb" },
{ name: "cc" }
]
]
transformArray( array1 )
transformArray( array2 )
function transformArray( array ){
const result = []
// destructure first array element for the first object:
const [ nameObj ] = array[0]
result.push( nameObj )
// map each object of the second array element into an
// an array of names, and then join the names together:
const dataObj = {}
dataObj.id = array[1].map(obj => obj.name).join('-')
dataObj.grouped = array[1]
result.push( dataObj )
console.log( result )
return result
}
I have this array which holds objects;
let arr = [
{
"id": 1,
"level": "2",
},
{
"id": 2,
"level": "3",
}
]
By default the array has keys starting from 0 and it looks like this:
[
0: {id: 1, level:2},
1: {id: 2, level:3}
]
How can I transform it so that the keys are the values of the property 'level'?
It should look like this:
[
2: {id:1, level:2},
3: {id:1, level:3}
]
So far I have tried this but it doesn't remove the original keys:
arr.map((v, k) => ({[v.level]: v}));
So I have something like this:
[
0: {2:
{id: 1, level:2}
},
1: {3:
{id: 2, level:3}
}
]
You need to populate a new array using reduce:
arr.reduce((prev, curr) => { prev[curr.level] = curr; return prev }, [])
I think I prefer the reduce method, but you could also construct an "array-like" (i.e. an object with numeric keys and a length property) and pass it to Array.from
const maxIdx = Math.max(...arr.map(v => parseInt(v.level, 10)))
const arrLen = maxIdx + 1;
const arrayLike = {
...Object.fromEntries(arr.map(v => [v.level, v])),
length: arrLen
};
const mappedArray = Array.from(arrayLike);
For output of
[undefined, undefined, {
"id": 1,
"level": "2"
}, {
"id": 2,
"level": "3"
}]
I have an array of objects of the structure coming from server response of iterated array object like as sample
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
......n
];
var arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
......n
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
......n
];
But now I want to append the array values inot single new array according to key following structure of as iterated values of above array Expected Output:
var finalObj = [
{
"id" : 1
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
{
"id" : 2
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
.....n
];
You can use reduce for concated arrays
const arrObj1 = [
{ id: '1', value: 21, value1: 13 },
{ id: '2', value: 21, value1: 13 },
];
const arrObj2 = [
{ id: '1', value3: 21, value14: 13 },
{ id: '2', value3: 21, value4: 13 },
];
const arrObj3 = [
{ id: '1', value5: 21, value6: 13 },
{ id: '2', value5: 21, value6: 13 },
];
const result = [...arrObj1, ...arrObj2, ...arrObj3].reduce(
(acc, { id, ...rest }) => ({ ...acc, [id]: acc[id] ? { ...acc[id], ...rest } : { ...rest } }),
{},
);
console.log(Object.entries(result).map(([id, data]) => ({ id, ...data })));
Push you arrays to a new array (you have to have your sub arrays in other list to loop through them) and then use flat, after that group your object according to the id property
var arrObj1 = [{
"id": "1",
"value": 21,
"value1": 13
},
{
"id": "2",
"value": 21,
"value1": 13
},
];
var arrObj2 = [{
"id": "1",
"value3": 21,
"value14": 13
},
{
"id": "2",
"value3": 21,
"value4": 13
},
];
var arrObj3 = [{
"id": "1",
"value5": 21,
"value6": 13
},
{
"id": "2",
"value5": 21,
"value6": 13
},
];
const input = [];
input.push(arrObj2, arrObj3);
const preResult = input.flat();
result = preResult.reduce((acc, x) => {
const index = acc.findIndex(y => y.id === x.id)
if (index >= 0) {
acc[index] = {
...acc[index],
...x
}
} else {
acc.push(x)
}
return acc;
}, arrObj1)
console.log(result)
You can iterate over array-length and push here for every entry 1 entry to the result. For getting this entry take a new object with the id and iterate over all (3 or perhaps more) arrays. For every array take the i-th entry and push for every key an entry with key:value (except for the key id itself).
Remark: You can use as much arrays you want and every object could contain as much value-prperties as you need. The only restriction is that every array has the same count of objects.
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 }
];
var arrObj2 = [
{"id":"1","value3":21, "value4":13},
{"id":"2","value3":21, "value4":13 }
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 }
];
let result =[];
let arrayAll = [arrObj1, arrObj2, arrObj3];
for (let i=0; i<arrayAll[0].length; i++) {
let obj = arrayAll[0][i];
let res = { id: obj.id};
for (let j=0; j<arrayAll.length; j++) {
let obj = arrayAll[j][i];
Object.keys(obj).forEach(key => {
if (key!='id') res[key] = obj[key];
})
}
result.push(res);
}
console.log(result);
Since you are using id to merge multiple objects, Map is one of the good option to merge.
let arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
];
let arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
];
let arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
];
let mergedArray = [...arrObj1,...arrObj2,...arrObj3].reduce((acc,curr) =>{
if(acc.has(curr.id)){
acc.set(curr.id, {...acc.get(curr.id),...curr});
}else{
acc.set(curr.id,curr);
}
return acc;
},new Map())
console.log(Array.from(mergedArray,x=>x[1]));
I have two array of objects:
`let arr1 = [
{"var1":1, "id": 1},
{"var2":2, "id": 2},
{"var3":3, "id": 3}]
`let arr2 = [
{"someVal":1, "data":123, "id": 1},
{"someVal":2, data":456, "id": 2}]
I need to add in to objects in 'arr1' parameters someVal from objects in arr2 by id's.
Result should be
`let arr1 = [
{"var1":1, "id": 1, "someVal":1},
{"var2":2, "id": 2, "someVal":1},
{"var3":3, "id": 3}]
Would that work for you?
const arr1 = [{"var1":1,"id":1},{"var2":2,"id":2},{"var3":3,"id":3}],
arr2 = [{"someVal":1,"id":1},{"someVal":2,"id":2}]
result = arr1.map(o => {
const someVal = arr2.find(({id}) => o.id == id)?.someVal
return {...o, ...(someVal ? {someVal} : {})}
})
console.log(result)
.as-console-wrapper{min-height:100%;}
You could use two forEach loops to add the corresponding values to arr1.
let arr1 = [
{"var1":1, "id": 1},
{"var2":2, "id": 2},
{"var3":3, "id": 3}]
let arr2 = [
{"someVal":1, "id": 1},
{"someVal":2, "id": 2}]
arr1.forEach(elem_arr1 => {
arr2.forEach(elem_arr2 => {
if(elem_arr1.id == elem_arr2.id){
elem_arr1["someVal"]= elem_arr2.someVal
}
})
})
console.log(arr1)
arr1.forEach((element) => {
arr2.map(item => {
if(element.id == item.id)
element.someVal = item.someVal;
})
});
you can use forach and object.assign to achieve this
let arr1 = [{"var1":1, "id": 1},{"var2":2, "id": 2},{"var3":3, "id": 3}]
let arr2 = [{"someVal":1, "data":123, "id": 1},{"someVal":2, "data":456, "id": 2}]
arr1.forEach(o=>{arr2.forEach(y=>{ if(o.id==y.id) Object.assign(o,y)})})
console.log(arr1)
array1 = [{
"id": 1,
"name": "aaa",
},
{
"id": 2,
"name": "bbb"
},
{
"id": 5,
"name": "ccc"
},
{
"id": 6,
"name": "ddd"
},
{
"id": 8,
"name": "eee"
},
{
"id": 12,
"name": "fff"
}]
array2 = [ 5, 6, 8 ,12]
Resulting Array = [ {name: "ccc"}, {name: "ddd"} , {name: "eee"}, {name: "fff"} ]
I am looking to map both arrays to get matching id numbers and get copy the names in the resulting arrray but I didn't succeed. Can you please suggest me how to do it?
Thank you
You could try the following. Basically, you're filtering the first array based on whether or not the id exists in the 2nd array and then mapping it back by only selecting the key(s) you want.
var resultArray = array1.filter(function(arr) {
return array2.indexOf(arr.id) !== -1;
}).map(function(item) {
return {
name: item.name
};
});
Let's turn array1 into an object first, that maps ids to the corresponding objects:
var idMap = {}
array1.forEach(function(element) {
idMap[element.id] = element
})
You can then get the result you want by doing
var result = array2.map(function(id) {
return idMap[id]
});
Try This:
array1 = [{"id": 1,"name": "aaa"},{"id": 2,"name": "bbb"},{"id": 5,"name": "ccc"},{"id": 6,"name": "ddd"},{"id": 8,"name": "eee"},{"id": 12,"name": "fff"}] ;
array2 = [ 5, 6, 8 ,12];
var result = array1.filter(item => array2.includes(item.id)).map(({id,name}) => ({name}));
console.log( result );