How to inject a new property into a JavaScript spread operator - javascript

I am attempting to update an existing array of objects by adding a new object:
const oldArray = [{ name: 'First', value: 'one' }, { name: 'Second', value: 'two' }, { name: 'Third', value: 'three' }]
const newArray = [...oldArray, { name: 'Fourth', value: 'four' }]
My intention, however, is to set up newArray so that the Fourth object becomes the 3rd item (index 2) in oldArray. How can I go about setting up newArray so that the new object is injected as the 3rd item in the ...oldArray spread operator, without having to write out all of the oldArray items again in newArray?

You can use .slice() along with the spread syntax.
const oldArray = [{ name: 'First', value: 'one' }, { name: 'Second', value: 'two' }, { name: 'Third', value: 'three' }]
const newArray = [...oldArray.slice(0, 2), { name: 'Fourth', value: 'four' }, ...oldArray.slice(2)];
console.log(newArray);

You would need to do two spreads using slice
const oldArray = [{ name: 'First', value: 'one' }, { name: 'Second', value: 'two' }, { name: 'Third', value: 'three' }]
const newArray = [...oldArray.slice(0,2), { name: 'Fourth', value: 'four' }, ...oldArray.slice(2)]
console.log(newArray.map(x => x.name));
other option is to just use splice()
const oldArray = [{ name: 'First', value: 'one' }, { name: 'Second', value: 'two' }, { name: 'Third', value: 'three' }]
const newArray = [...oldArray]
newArray.splice(2,0,{ name: 'Fourth', value: 'four' });
console.log(newArray.map(x => x.name));

Related

How to push id of parent object to child objects?

I have an array of object which has an inner array of object, I want to push the id of parent object to each child object.
a = [
{id: 'abc', stage: [{name: 'car' , value: '123'},{name: 'bus' , value: '345'},{name: 'truck' , value: '567'}],
{id: 'def', stage: [{name: 'bike' , value: '890'},{name: 'cycle' , value: '123'},{name: 'car' , value: '456'}]}
]
expected output = [
{name: 'car' , value: '123', id: 'abc'},{name: 'bus' , value: '345', 'abc'},{name: 'truck' , value: '567', 'abc'}, {name: 'bike' , value: '890', id: 'def'},{name: 'cycle' , value: '123',id: 'def',id: 'def'},{name: 'car' , value: '456', id: 'def'}
]
Im able to get the only the stage but not able to push id to each object. pls help
const getAllStages = [].concat(...map(a, el => el.stage));
console.log(getAllStages )
Use .map() again to add el.id to each element of el.stage.
You can use .flatMap() in the outer mapping to concatenate all the results into a single array.
const a = [
{id: 'abc', stage: [{name: 'car' , value: '123'},{name: 'bus' , value: '345'},{name: 'truck' , value: '567'}]},
{id: 'def', stage: [{name: 'bike' , value: '890'},{name: 'cycle' , value: '123'},{name: 'car' , value: '456'}]}
]
result = a.flatMap(({
id,
stage
}) => stage.map(s => ({
id: id,
...s
})));
console.log(result);
If you're trying to merge in id:
let remapped = a.map(e => ({ id: a.id, ...e }));
Where that converts each entry into an object inheriting the a.id value and adding on whatever else is in the object.
Here is a example and result :)
a.forEach(function(row) {
row.stage.map(function (child) {child.id = row.id})
})
result:
[{"id":"abc","stage":[{"name":"car","value":"123","id":"abc"},{"name":"bus","value":"345","id":"abc"},{"name":"truck","value":"567","id":"abc"}]},{"id":"def","stage":[{"name":"bike","value":"890","id":"def"},{"name":"cycle","value":"123","id":"def"},{"name":"car","value":"456","id":"def"}]}]
You can write like this without using libraries
let a = [
{
id: 'abc', stage:
[
{ name: 'car', value: '123' },
{ name: 'bus', value: '345' },
{ name: 'truck', value: '567' }
]
},
{
id: 'def', stage:
[
{ name: 'bike', value: '890' },
{ name: 'cycle', value: '123' },
{ name: 'car', value: '456' }
]
}
]
let output = [];
for (const element of a) {
for (const stageElement of element.stage) {
let newElement = {
name: stageElement.name,
value: stageElement.value,
id: element.id
};
output.push(newElement);
}
}
const a = [
{id: 'abc', stage: [{name: 'car' , value: '123'},{name: 'bus' , value: '345'},{name: 'truck' , value: '567'}]},
{id: 'def', stage: [{name: 'bike' , value: '890'},{name: 'cycle' , value: '123'},{name: 'car' , value: '456'}]}
]
a.forEach(item => {
const itemId = item.id;
const stages = item.stage;
stages.forEach(stage => {
stage['id'] = itemId;
})
});
console.log(a);

Trying to find multiple objects from array when given multiple keys in an array

I'm going to be given an array of label text strings to match to values in an array. The array of objects is static but the array of text strings will be dynamic from user input. I want to know the best es6 way of setting this up using filter or map.
Here is the static array of objects:
const counts = [
{label: '0-0', value: 1},
{label: '0-1', value: 2},
{label: '0-2', value: 3},
{label: '1-0', value: 4},
{label: '1-1', value: 5},
{label: '1-2', value: 6},
{label: '2-0', value: 7},
{label: '2-1', value: 8},
{label: '2-2', value: 9},
{label: '3-0', value: 10},
{label: '3-1', value: 11},
{label: '3-2', value: 12},
];
This is an example of the array of keys I'll get:
Array [
"0-2",
"1-2",
"2-0",
"3-1"
]
So the results I want to get are an array with the values:
[3,6,7,11]
I have ways of doing this sloppily checking each value one by one, I'm just not sure what to use like filter, map, reduce, or find.
We can use filter and map function of JS for this.
let test = [
"0-2",
"1-2",
"2-0",
"3-1"
];
let counts = [{
label: '0-0',
value: 1
},
{
label: '0-1',
value: 2
},
{
label: '0-2',
value: 3
},
{
label: '1-0',
value: 4
},
{
label: '1-1',
value: 5
},
{
label: '1-2',
value: 6
},
{
label: '2-0',
value: 7
},
{
label: '2-1',
value: 8
},
{
label: '2-2',
value: 9
},
{
label: '3-0',
value: 10
},
{
label: '3-1',
value: 11
},
{
label: '3-2',
value: 12
},
];
let answer = counts.filter(item => (
test.includes(item.label)
)).map(item => item.value)
console.log(answer);
You can use array#reduce and add the matched label's value in that using array#find.
const counts = [{ label: '0-0', value: 1 }, { label: '0-1', value: 2 }, { label: '0-2', value: 3 }, { label: '1-0', value: 4 }, { label: '1-1', value: 5 }, { label: '1-2', value: 6 }, { label: '2-0', value: 7 }, { label: '2-1', value: 8 }, { label: '2-2', value: 9 }, { label: '3-0', value: 10 }, { label: '3-1', value: 11 }, { label: '3-2', value: 12 }, ],
input = [ "0-2", "1-2", "2-0", "3-1" ],
output = input.reduce((arr, label) => {
const matched = counts.find(o => o.label === label);
if(matched) arr.push(matched.value);
return arr;
},[]);
console.log(output);
You can create a Map which will act as a look-up-table (lut) for labels and their associated values. Using the Map you can then .map() your array of labels to be the value from the Map object.
By using this approach, you will only need to loop through your counts array once, and your labels array (arr) once, which will allow you to avoid "checking each value one by one", providing you with a complexity of ~ O(n + k), rather than O(nk):
const counts = [{label:"0-0",value:1},{label:"0-1",value:2},{label:"0-2",value:3},{label:"1-0",value:4},{label:"1-1",value:5},{label:"1-2",value:6},{label:"2-0",value:7},{label:"2-1",value:8},{label:"2-2",value:9},{label:"3-0",value:10},{label:"3-1",value:11},{label:"3-2",value:12}];
const arr = ["0-2", "1-2", "2-0", "3-1"];
const lut = new Map(counts.map(({label, value}) => [label, value]));
const res = arr.map(label => lut.get(label));
console.log(res);

Compare two arrays and add new keys based on Index of both Arrays

I am creating a sunburst chart in highcharts and I am having trouble creating layers in the array.
For instance, the headers array is layer 2 and data array is layer 3.
I need to compare the headername with groups from data and create a new array giving both a child id and a parent id.
Have posted my current solution below the code.
const headers = ['Cars', 'Fruits', 'Food'];
const data = [{
group: 'Cars',
name: 'BMW',
value: '25641'
}, {
group: 'Fruits',
name: 'Apple',
value: '45876'
},
{
group: 'Cars',
name: 'Benz',
value: '65784'
},
{
group: 'Cars',
name: 'Toyota',
value: '254'
},
{
group: 'Food',
name: 'Pizza',
value: '87535'
},
{
group: 'Cars',
name: 'Honda',
value: '65796'
},
{
group: 'Fruits',
name: 'Banana',
value: '98631'
},
{
group: 'Fruits',
name: 'Orange',
value: '87563'
},
{
group: 'Food',
name: 'Burger',
value: '78324'
},
{
group: 'Fruits',
name: 'Mango',
value: '24598'
}
]
This is what I tried.
const newArray = headers.map(function(itemA, indexA) {
return data.map(function(itemB, indexB) {
return {
id: `3.${indexB + 1}`,
parentId: `2.${indexA + 1}`,
value: itemB.value,
name: itemB.name
}
})
})
This is the output I expect:
const newArray = [{
id: '3.1',
parentId: '2.1',
name: 'BMW',
value: '25641'
}, {
id: '3.2',
parentId: '2.2',
name: 'Apple',
value: '45876'
},
{
id: '3.3',
parentId: '2.1',
name: 'Benz',
value: '65784'
},
{
id: '3.4',
parentId: '2.1'
name: 'Toyota',
value: '254'
},
{
id: '3.5',
parentId: '2.3',
name: 'Pizza',
value: '87535'
},
{
id: '3.6',
parentId: '2.1',
name: 'Honda',
value: '65796'
},
{
id: '3.7',
parentId: '2.2',
name: 'Banana',
value: '98631'
},
{
id: '3.8',
parentId: '2.2',
name: 'Orange',
value: '87563'
},
{
id: '3.9',
parentId: '2.3',
name: 'Burger',
value: '78324'
},
{
id: '3.10',
parentId: '2.2',
name: 'Mango',
value: '24598'
}
]
You don't need the nested maps — it will cause nested arrays of results. You just need one because there is a 1-to1 relationship between data and your expected output. You can just map() over data and lookup the parent index as you go.
const headers = ['Cars', 'Fruits', 'Food'];
const data = [{group: 'Cars',name: 'BMW',value: '25641'}, {group: 'Fruits',name: 'Apple',value: '45876'},{group: 'Cars',name: 'Benz',value: '65784'},{group: 'Cars',name: 'Toyota',value: '254'},{group: 'Food',name: 'Pizza',value: '87535'},{group: 'Cars',name: 'Honda',value: '65796'},{group: 'Fruits',name: 'Banana',value: '98631'},{group: 'Fruits',name: 'Orange',value: '87563'},{group: 'Food',name: 'Burger',value: '78324'},{group: 'Fruits',name: 'Mango',value: '24598'}]
const newArray = data.map(function(itemB, indexB) {
let parentIndex = headers.indexOf(itemB.group) // just find the parent index
return {
id: `3.${indexB + 1}`,
parentId: `2.${parentIndex + 1}`,
value: itemB.value,
name: itemB.name
}
})
console.log(newArray)

How to replace existing array objects of one array to another array in javascript

var arr1 = [{
id: '111',
name: 'aaa'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'ccc'
}, {
id: '444',
name: 'ddd'
}];
var arr2 = [{
id: '111',
name: 'xyz'
}, {
id: '333',
name: 'abc'
}];
my requirement: I need to replace aar1 with arr2 having same id in arr2 but different name value.
Below Result i should get in arr1
var arr1 = [{
id: '111',
name: 'xyz'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'abc'
}, {
id: '444',
name: 'ddd'
}];
you can use map and find to replace arr2 name in arr1.
map function iterate through each elements of arr1, find will match both id and return matched object if found. if we don't find we will just return arr1 item using || operator.
const result = arr1.map(item => arr2.find(item2 => item.id === item2.id) || item)
Working example:
var arr1 = [{
id: '111',
name: 'aaa'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'ccc'
}, {
id: '444',
name: 'ddd'
}];
var arr2 = [{
id: '111',
name: 'xyz'
}, {
id: '333',
name: 'abc'
}];
const result = arr1.map(item => arr2.find(item2 => item.id === item2.id) || item)
console.log(result)
This is my interpretation of the question.
Only copy the name if the id is found in arr2.
arr1.forEach(e1 => {
var e2 = arr2.find( e => e.id === e1.id );
if (e2) { e1.name = e2.name; }
});

How to remove object from array if property in object do not exist

I have the following collection of data
[{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
},
id: '4',
date: '2017-01-02',
value: 3
}]
I want to delete any object that does not have the 'date' property. In the example above, the object with the id 3 should be deleted.
The finished object should look like this
[{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
id: '4',
date: '2017-01-02',
value: 3
}]
I tried to find and delete a undefined value with lodash. It does not work. The object looks exactly as it is entering.
_.each(obj, (val) => {
_.remove(val, value => value['XXX-BUDAT'] === undefined);
});
How can I use lodash for this purpose?
Thanks in advance
You can use .filter(), Object.keys(), and .includes()
let input = [
{ id: '1', date: '2017-01-01', value: 2},
{ id: '2', date: '2017-01-02', value: 3},
{ id: '3', value: 3 },
{ id: '4', date: '2017-01-02', value: 3 }
]
let output = input.filter(obj => Object.keys(obj).includes("date"));
console.log(output);
You can filter the array based on that property like this:
const initial = [{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
}, { // this left curly brace was missing!, check that out
id: '4',
date: '2017-01-02',
value: 3
}
];
const finalR = initial.filter((obj) => obj.hasOwnProperty('date') && !!obj.date);
console.log(finalR);
You can use Array#filter and Object#hasOwnProperty to do so:
var newArray = oldArray.filter(function(obj) {
return obj.hasOwnProperty("date");
});
Which can be shortened out using an arrow function:
var newArray = oldArray.filter(obj => obj.hasOwnProperty("date"));
Lodash solution:
var newArray = _.filter(oldArray, obj => _.has(obj, "date"));
Example:
var oldArray = [{id: '1', date: '2017-01-01', value: 2 }, { id: '2', date: '2017-01-02', value: 3 }, { id: '3', value: 3 }, {id: '4', date: '2017-01-02', value: 3}];
var newArray = oldArray.filter(obj => obj.hasOwnProperty("date"));
console.log(newArray);
You can use Array.prototype.filter. In addition, you can use ES6 object assignment destructiring to make it concise:
var data=[{id:'1',date:'2017-01-01',value:2},{id:'2',date:'2017-01-02',value:3},{id:'3',value:3},{id:'4',date:'2017-01-02',value:3}];
var result = data.filter(({date}) => date);
console.log(result)
First of all your array of object is not valid, fix it by wrapping the last object element with preceding curly brace {. See Array.prototype.filter() and Object.prototype.hasOwnProperty() that'll check your current object item has the date key or not? if it has then it'll return that object other wise that item will not return.
var array_of_object = [{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
},
{ //missing brace here
id: '4',
date: '2017-01-02',
value: 3
}
];
function filterByValue(item) {
return item.hasOwnProperty('date');
}
var arrByID = array_of_object.filter(filterByValue);
console.log(arrByID);
This is a native javascript solution:
var arr = [
{id: '1', date: '2017-01-01', value: 2},
{id: '2', date: '2017-01-02', value: 3},
{id: '3', value: 3},
{id: '4', date: '2017-01-02', value: 3}
]
for(var i = 0; i < arr.length; i++) {
if(!arr[i].hasOwnProperty("date")) {
arr.splice(i,1);
}
}
console.log(arr);

Categories

Resources