Swap array keys with inner object value - javascript

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"
}]

Related

flatten array and put child array into an array of object

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
}

Sort an array by a list of it's fields

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);

Add parameters from one array of objects to enother by identifier

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)

Map both arrays and copy result in new array

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 );

merging two array objects using loadash

Can anyone help me in merging of two array of objects please using loadash in javascript? Below is the example arrays. I tried with _merge
arr 1= [
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1
},
{
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1
}
]
arr2 =[
{
"id": 1,
"name": "BN",
}
]
arrResult =[
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1,
"id": 1,
"name": "BN"
}, {
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1,
"id": 1,
"name": "BN"
}
]
I tried with below option but it is returning only one record.
var arrResult = _(list).keyBy('businessExecutiveId').merge(_.keyBy(this.typeaheadDataList, 'id')).values() .value();
I also tried with below
const c = _.assign([], arr1, arr2);
reslut I am getting is like below
{
id: 1,
name: "BN"
},
{
areaId: 1,
areaName: "ASas",
businessExecutiveId: 1,
id: 1,
name: "BN"
}
Please help me
You don't need lodash to do this. Why not just use javascripts reduce function to merge all object keys from arr2 objects into the objects of array 1, like so
arr1.reduce((arr, obj) => {
const newObj = arr2.reduce((o, insideObj) => ({
...o,
...insideObj
}), obj)
return [...arr, newObj]
}, [])
arr1.reduce((arr, obj) => {
const newObj = arr2.reduce((o, insideObj) => ({
...o,
...insideObj
}), obj)
return [...arr, newObj]
}, [])
I resolved it by using below code.
_.map(list, function(item) {
return _.merge(item, _.find(temp, function(o) {return o.id == item.businessExecutiveId }) );
});
If we had array comprehension, we could have used something like this:
[
for (a of arr1)
for (b of arr2)
if(a.businessExecutiveId === b.id) {...a, ...b}
]
Without array comprehension, we use flatMap:
_(arr1).flatMap(a =>
_(arr2).flatMap(b =>
a.businessExecutiveId === b.id ? [{...a, ...b}] : []
).value()
).value()
var arr1= [
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1
},
{
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1
},
{
"areaId": 3,
"areaName": "bname",
"businessExecutiveId": 2
}
]
var arr2= [
{
"id": 1,
"name": "BN",
},
{
"id": 2,
"name": "CM",
}
]
res = _(arr1).flatMap(a =>
_(arr2).flatMap(b =>
a.businessExecutiveId === b.id ? [{...a, ...b}] : []
).value()
).value()
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Categories