Match array values and create final array - Javascript - javascript

I have below array. First object is the original data. Inside array is the changed value. I am trying to create a final data by matching with the Name field with inside array. which should look like
var a =
[
{"Id":"1","Test":"Name1","Name":"hunt9988ggggggggggggdfsf1111"},
{"Id":"2","Test":"Name2","Name":"hunt9988ggggggggggggdfsf"},
[
**{"Name":"hunt9988ggggggggggggdfsf1118","Id":"1"}, // Changed value
{"Name":"hunt9988ggggggggggggdfsf1118","Id":"2"}**
]
]
Final Data
var a =
[
{"Id":"1","Test":"Name1","Name":"hunt9988ggggggggggggdfsf1118"},
{"Id":"2","Test":"Name2","Name":"hunt9988ggggggggggggdfsf1118"}
]
I am trying with below code
var result = a.map(item => ({ value: item.Id, text: item.Name}));
console.log(result)

Like this?
Note I modify the original array
let a = [{
"Id": "1",
"Test": "Name1",
"Name": "hunt9988ggggggggggggdfsf1111"
},
{
"Id": "2",
"Test": "Name2",
"Name": "hunt9988ggggggggggggdfsf"
},
[{
"Name": "hunt9988ggggggggggggdfsf1118",
"Id": "1"
}, // Changed value
{
"Name": "hunt9988ggggggggggggdfsf1118",
"Id": "2"
}
]
]
const replaceArray = a.find(item => Array.isArray(item))
replaceArray.forEach(item => a.find(aItem => aItem.Id === item.Id).Name=item.Name)
a = a.filter(item => item.Id)
console.log(a)

Related

javascript how to replace data where id match

I have a data like this in array.
[
{
"teamName": "TeamA",
"players": ["1","2"]
},
{
"teamName": "TeamB",
"players": ["2"]
}
]
and I want to replace players id which match in other array
players = [
{
"id": "1",
"playername": "alex"
},
{
"id": "2",
"playername": "john"
}
]
So output will be like this
[
{
"teamName": "TeamA",
"players": [
{
"id": "1",
"playername": "alex"
},
{
"id": "2",
"playername": "john"
}]
},
{
"teamName": "TeamB",
"players": [
{
"id": "2",
"playername": "john"
}]
}
]
I tried to find by for loop and where it will find and replace but that's not working for me.
you can do this by iterating over first array and updating the players property of each element in that array.
let arrOne = [
{
"teamName": "TeamA",
"players": ["1","2"]
},
{
"teamName": "TeamB",
"players": ["2"]
}
]
players = [
{
"id": "1",
"playername": "alex"
},
{
"id": "2",
"playername": "john"
}
]
// solution
arrOne.forEach( teamObject => {
let newPlayerArray = [];
teamObject.players.forEach( id => {
let newPlayerObject = {};
newPlayerObject.id = id;
newPlayerObject.playername = players.find( player => player.id == id)?.playername;
newPlayerArray.push(newPlayerObject)
})
teamObject.players = newPlayerArray;
})
One approach:
// defining the variables, naming 'teams' as it was unnamed in
// the original post:
let teams = [
{
"teamName": "TeamA",
"players": ["1", "2"]
},
{
"teamName": "TeamB",
"players": ["2"]
}
],
// updated the name of this Array of Objects due to the naming
// clash between the original name ('players') when using
// destructuring assignments while iterating the 'teams' Array,
// because of an identically-named property:
playerDetails = [{
"id": "1",
// I updated this property-name to use camelCase consistently:
"playerName": "alex"
},
{
"id": "2",
"playerName": "john"
}
],
// rather than editing the original Array, we create a new one
// by iterating over the teams Array, using Array.prototype.map():
combined = teams.map(
// using destructuring assignement to retrieve the named properties
// of the Object passed in to the function:
({
teamName,
players
}) => {
// because we're returning an Object literal, we have to use return and wrap
// the anonymous callback function of the Arrow function in curly braces ('{...}')
// to avoid the returned Object-literal being misinterpreted as a function body:
return {
// we return the teamName property unchanged:
teamName,
// but here we update the players property, we iterate over the players Array,
// again using players.prototype.map() to update the existing Array based on the
// result of actions taken in the anonymous Arrow function:
players: players.map(
// we pass in a reference to the 'id' enclosed within the player Array,
// giving it a verbose/clear name given that 'id' would be a sensible/short
// name, but is used within the enclosed function as the named property of
// the other function we're working with.
// within the anonymous function we use Array.prototype.find():
(teams_playerID) => playerDetails.find(({
// passing in a reference to the 'id' property-name of the Object
// within the playerDetails Array:
id
// and here we check to see if the 'id' of the playerDetails Array is
// exactly-equal to the teams_playerID variable; if so this Object is
// returned and the 'players' Array is updated, and changed from a String
// to the found Object; if no match is found the current 'players' Array-value
// is unchanged:
}) => id == teams_playerID ))
}
});
console.log(combined);
// [{"teamName":"TeamA","players":[{"id":"1","playerName":"alex"},{"id":"2","playerName":"john"}]},{"teamName":"TeamB","players":[{"id":"2","playerName":"john"}]}]
JS Fiddle demo.
References:
Array.prototype.find().
Array.prototype.map().
Arrow functions.
Destructuring assignemnt.
You can build the result by stepping through the list of teams, looking up each player by their id, and adding the player record to the result’s players array.
const teams = [
{
"teamName": "TeamA",
"players": ["1", "2"]
},
{
"teamName": "TeamB",
"players": ["2"]
}
]
const players = [
{
"id": "1",
"playername": "alex"
},
{
"id": "2",
"playername": "john"
}
]
let result = []
teams.forEach(team => {
let record = {
"teamname": team.teamName,
"players": []
}
team.players.forEach(player_id => {
record.players.push(players.find(p => p.id === player_id))
})
result.push(record)
})
console.log(JSON.stringify(result, null, 4))

How to update object based off objects specific value?

I have 2 objects and I want to 'transplant' values from one object into the other.
The first object I am drawing data from looks like:
var userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
Name: "Account 2"
},
]
}
The 2nd object I am placing data into looks like:
[
{
"name": "Account 1",
"data": [
0,
0
],
},
{
"name": "Account 2",
"data": [
0,
0
],
}
]
My goal is to take the Amount form the first object and place it in the data array of the 2nd. Each year corresponds to a value in the 'data` array.
So, the resulting updated object should look like:
[
{
"name": "Account 1",
"data": [
430140.68,
0
],
},
{
"name": "Account 2",
"data": [
0,
458997.32
],
}
]
To try to achieve this I have the following code:
const yearArrLength = yearsArr.length;
const generatedObj = new Array(yearArrLength).fill(0);
// Push name and populate data array with 0s.
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
if (!generatedObj.find(key => key.name === accName)){
generatedObj.push({'name': accName, 'data': blankDataArr});
}
}
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
var accAmount = userData.Data[key].Amount;
var accYear = userData.Data[key].Year;
// Get location of years array value
var yearArrIndex = yearsArr.indexOf(accYear);
for (var key of Object.keys(generatedObj)) {
if (generatedObj[key].name == accName) {
generatedObj[key].data[yearArrIndex] = accAmount;
}
}
}
However, this seems to populate all of the data array values, eg:
[
{
"name": "Account 1",
"data": [
430140.68,
458997.32
],
},
{
"name": "Account 2",
"data": [
430140.68,
458997.32
],
}
]
I'm completely stumped as to why. The if statement should be checking if there is a matching account name, but it doesn't seem to fire.
Would anyone know what I've done wrong?
It looks like you're pushing the exact same blankDataArr each time - you're not pushing a new array, you're pushing the same array to all.
For a more minimal example:
const subarr = [];
const arr = [subarr, subarr];
arr[0].push('x');
console.log(JSON.stringify(arr));
// both items in `arr` have changed
// because both refer to the exact same subarr object
For what you're trying to do, it looks like it'd be a lot easier to make an object or Map indexed by AccountName first, that way you just have to access or create the AccountName property while iterating, and assign to the appropriate year.
const yearsArr = ['2015', '2016'];
const userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
AccountName: "Account 2"
},
]
};
const dataByAccountName = new Map();
for (const { AccountName, Amount, Year } of userData.Data) {
if (!dataByAccountName.has(AccountName)) {
// Create an entirely new array:
dataByAccountName.set(AccountName, yearsArr.map(() => 0));
}
const index = yearsArr.indexOf(Year);
dataByAccountName.get(AccountName)[index] = Amount;
}
const result = [...dataByAccountName.entries()].map(([name, data]) => ({ name, data }));
console.log(result);

Porblem on Getting Array Inside of Array

I have a problem on an object inside of an array and I wanted to display only that as an array.
data1
const data1 = [
{
"id": "01",
"info": "fefef",
"sub": "hieei",
"details": {
"data": "fruits"
}
},
{
"id": "02",
"info": "fefef",
"sub": "hieei",
"details": {
"data": "things"
}
}
]
expected output
const final= [
{
"data": "fruits"
},
{
"data": "things"
}
]
Code
const final = data.map((data) => { ...data})
map over the array and return a new object using the details property. If you don't return a new object, your new array will still carry references to the objects in the original array. So if you change a value of a property in that original array, that change will be reflected in the new array too, and you probably don't want that to happen.
const data1=[{id:"01",info:"fefef",sub:"hieei",details:{data:"fruits"}},{id:"02",info:"fefef",sub:"hieei",details:{data:"things"}}];
// Make sure you return a copy of the
// details object otherwise if you change the details
// of the original objects in the array
// the new mapped array will carry those object changes
// because the array objects will simply references to the old objects
const out = data1.map(obj => {
return { ...obj.details };
});
console.log(out);
Map through the array and extract its details property:
const data1 = [
{
"id": "01",
"info": "fefef",
"sub": "hieei",
"details": {
"data": "fruits"
}
},
{
"id": "02",
"info": "fefef",
"sub": "hieei",
"details": {
"data": "things"
}
}
]
const res = data1.map(e => e.details)
console.log(res)
Using map and destructuring will simplify.
const data1 = [
{
id: "01",
info: "fefef",
sub: "hieei",
details: {
data: "fruits",
},
},
{
id: "02",
info: "fefef",
sub: "hieei",
details: {
data: "things",
},
},
];
const res = data1.map(({ details: { data } }) => ({ data }));
console.log(res);
// if you just need the details object
const res2 = data1.map(({ details }) => details);
console.log(res2);

How to get only specific elements from array by comparing them in javascript?

I have two arrays.Second arrayB has some elements identical to arrayA. Now after comparing the arrays arrayA should have only those values those are not in arrayB. Please tell me best way to do it.
let arrayA = [{ "displayName": "John" }, { "displayName": "Sandra" },{ "displayName": "Peter" }]
let arrayB = [{ "name": "Bobby" }, { "name": "John" }, { "name": "Sandra" }]
arrayA.forEach(function(cust, index) {
arrayB.forEach(function(comp) {
if (comp.name == cust.displayName) {
delete arrayA[index]
}
})
})
console.log("Final"+JSON.stringify(arrayA))
Output -> Final[null,null,{"displayName":"Peter"}]
Filter and only keep the ones that do not exist in the other array
let arrayA = [{ "displayName": "John" }, { "displayName": "Sandra" },{ "displayName": "Peter" }]
let arrayB = [{ "name": "Bobby" }, { "name": "John" }, { "name": "Sandra" }]
arrayA = arrayA.filter(a =>
!arrayB.find(b => a.displayName === b.name)
);
console.log("Final"+JSON.stringify(arrayA))
To remove the elements, that aren't contained by arrayB you can use map() and filter():
arrayB = arrayB.map((key) => key.name)
arrayA = arrayA.filter((key) => arrayB.includes(key.displayName))
In the first line you'll get an array with only names
In the second line you'll remove from arrayA elements, that aren't in arrayB
You can also add map():
arrayB = arrayB.map((key) => key.name)
arrayA = arrayA.filter((key) => arrayB.includes(key.displayName))
.map((key) => key.displayName)
So you'll have in second array only names, but not objects.
let arrayA = [{ "displayName": "John" }, { "displayName": "Sandra" },{ "displayName": "Peter" }]
let arrayB = [{ "name": "Bobby" }, { "name": "John" }, { "name": "Sandra" }]
const shouldFilterOutByName = {};
for (let item of arrayB) {
shouldFilterOutByName[item.name] = true;
}
const filteredAry = arrayA.filter(item => !shouldFilterOutByName[item.displayName]);
console.log(filteredAry);
Taplar's solution is probably the one you want. The reason I haven't deleted my answer is in case time complexity is important. Taplar's solution has time complexity of O(n^2) and my solution is O(n).

ES6 map array of objects to array

There is an array of objects
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}]
and I would like to map this array of objects in order to get just array
["Date 1","08/20/2018","Date 2","12/23/2018"]
I'm trying using .map()
data.map((d, i) =>
`${'Date ' + i}`
d.name
)];
but cannot map name with the first (d) parameter.
Because the input items and output array items aren't one-to-one, you won't be able to use .map. Use reduce instead:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.reduce((a, { name }, i) => {
a.push('Date ' + (i + 1), name);
return a;
}, []);
console.log(output);
Or .flatMap:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.flatMap(({ name }, i) => (['Date ' + (i + 1), name]));
console.log(output);
(note that since arrays are zero-indexed, you'll have to use i + 1, not i, if you want the first item in the output array to start at 1 instead of 0)
You can't use map since that method produce a new array with the same number of items of the original ones.
However, you can use flatMap (where supported) to achieve the your desired result:
data.flatMap(({name}, i) => [`Date ${i + 1}`, name]);
console.log(data) // [ "Date 1", "08/20/2018", "Date 2", "12/23/2018" ]
Basically flatMap is like calling map and then flat; therefore if from the callback function we returns an array per item, this array will be flattened before returned.
Regular map call would have been produced [[ "Date 1", "08/20/2018"], ["Date 2", "12/23/2018"]] instead.
Try to combine map and flatmap methods in order to achieve desired result:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flatMap(f=> f);
console.log(result)
or using flat method:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flat(1);
console.log(result)
One line answer using ES2019 Array.flat :
data.map((item,index)=>([`Date${index+1}`,item.name])).flat();
But in my opinion, it is not optimized when there is huge data.
I appreciate above answers but if you still prefer to use .map() method to accomplish your work, you can do it.
Just with an additional use of concat() method with map() method. Let's see how.
I have used ...data,map() statement where ... is used for Array destructuring. More information can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring.
const data = [
{
"name": "08/20/2018",
"id": "name_1"
},
{
"name": "12/23/2018",
"id": "name_2"
}
]
output = new Array() // or just []
output = output.concat(...data.map((obj, index) => [`Date ${index + 1}`, obj.name]))
console.log(output)
// [ 'Date 1', '08/20/2018', 'Date 2', '12/23/2018' ]
Screenshot

Categories

Resources