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 );
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 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;
}
}
})
Let's say I have an array of objects:
Objects = [
{ "id": 1, "name": Joseph, function: "preacher"},
{ "id": 2, "name": Ann, function: "singer"},
{ "id": 3, "name": Miles, function: "preacher"},
{ "id": 4, "name": Jack, function: "singer"},
{ "id": 5, "name": Igor, function: "secretary"}
];
And also an array of properties:
sort = ['function', 'name'];
I have to sort the Objects array, using a combination of properties(sort array).
So I did it like this:
const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });
Objects.sort(
(x, y) =>
(intlCollator.compare(x[sort[0]], y[sort[0]])) ||
(intlCollator.compare(x[sort[1]], y[sort[1]])) ||
(intlCollator.compare(x[sort[2]], y[sort[2]]))
);
How would I make the sorting dynamic?
I mean, iterate using variable sort combinations.
For example:
sort = ['function', 'name'];
Or:
sort = ['name'];
You could iterate the keys until a comparing returns a not falsy value.
const
objects = [{ id: 1, name: "Joseph", function: "preacher" }, { id: 2, name: "Ann", function: "singer" }, { id: 3, name: "Miles", function: "preacher" }, { id: 4, name: "Jack", function: "singer" }, { id: 5, name: "Igor", function: "secretary" }],
intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' }),
sort = ['function', 'name'];
objects.sort((a, b) => {
let r;
sort.some(k => r = intlCollator.compare(a[k], b[k]));
return r;
});
console.log(objects);
Since ES10 sort is stable. That means you can first sort using the first key, then sort the second and so on.
const Objects = [
{ "id": 1, "name": "Joseph", function: "preacher"},
{ "id": 2, "name": "Ann", function: "singer"},
{ "id": 3, "name": "Miles", function: "preacher"},
{ "id": 4, "name": "Jack", function: "singer"},
{ "id": 5, "name": "Igor", function: "secretary"}
];
const sort = ['name', 'function'];
const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });
sort.forEach(s => {
Objects.sort((l, r) => intlCollator.compare(l[s], r[s]));
});
console.log(Objects);
I have two array objects arrayA and arrayB.
let arrayA = [
{
"category": "red",
"rank": 8,
"phone": 12345
},{
"category": "black",
"rank": 7,
"phone": 12332
}
]
let arrayB = [
{
"category": "red",
"rank": 4,
},{
"category": "black",
"rank": 7,
}
]
return array should be
arrayA = [
{
"category": "red",
"rank": 8,
"phone": 12345
},{
"category": "black",
"rank": 7,
"phone": 12332
}
]
So in the above arrays category is unique for each object. so while comparing if any of the object's rank in arrayA is equal to or greater than respective with the object in arrayB then return the whole arrayA else return nothing.
In the above arrays in category of red, rank of arrayA is greater(rank -> 8) than the rank of arrayB(rank -> 4) in the red category so arrayA need to return.
In case if the in arrayA rank in category "red" is less than the rank of respective in arrayB then return nothing.
I tried some method but filter one is filtering out the object from array which do not satisfied the condition, but I want whole array as it is if any of the some method's condition satisfied in one or more object.
let arrayC = arraA.filter(o1 =>
arrayB.some(o2 =>
{return (o1.category=== o2.category&& o1.rank >= o2.rank)}));
can anybody help here?
If the order is not the same then you can Map to make it more efficient.
let arrayA = [
{
category: "red",
rank: 8,
phone: 12345,
},
{
category: "black",
rank: 7,
phone: 12332,
},
];
let arrayB = [
{
category: "red",
rank: 4,
},
{
category: "black",
rank: 7,
},
];
const map = new Map(arrayB.map((o) => [o.category, o]));
const result = arrayA.some((o) => o.rank >= map.get(o.category).rank) ? arrayA: [];
console.log(result);
You can concatenate the two arrays, and use a reducer.
Included logs so you can easily go through the code yourself.
const mergedArray = arrayA.concat(arrayB)
// We use a reducer to combine the merged Array.
mergedArray.reduce((acc, { category, rank, phone }) => {
console.log(`category: ${category} - rank: ${rank} - phone: ${phone}`)
// First find if the given category exist in accumulator
const foundCategoryObject = acc.find(a => a.category === category)
console.log(`foundCategoryObject: ${JSON.stringify(foundCategoryObject)}`)
// If not found, simply add the found current object to acc and return
if (!foundCategoryObject) return [...acc, { category: category, rank: rank, phone: phone }]
// If not found, check if the later object has higher or lower rank
else {
if (foundCategoryObject.rank >= rank) {
console.log(`"new" object has lower rank. Return original("old") object. (NO Change) ${category}-${rank}-${phone}`)
return acc
}
else {
console.log(`"new" object has higher rank. Return "nothing". Delete the "old" object and return acc. ${category}-${rank}-${phone}`)
return acc.filter(a => a.category !== category)
}
}
}, [])
Looks pretty simple, I have added another case in the example, can you let us know if this is what you were looking for.
I compare the category of both the arrays and then compare rank.
if only 'b' has a higher rank object with same name category, I remove the object from result/
let arrayA = [
{
"category": "red",
"rank": 8,
"phone": 12345
},{
"category": "black",
"rank": 7,
"phone": 12332
},
{
"category": "orange",
"rank": 6,
"phone": 12332
}
]
let arrayB = [
{
"category": "red",
"rank": 4,
},{
"category": "black",
"rank": 7,
},
{
"category": "orange",
"rank": 12,
}
]
// dic had key: category and value as ArrayB objects
let dic = arrayB.reduce((dic,v) => (dic[v.category] = v, dic) , {})
let result = arrayA.filter(a => dic[a.category].rank <= a.rank)
console.log(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"
}]