How can I iterate over an array? - javascript

I have this JSON structure:
const arr = [
{
id: "TaskStatuses",
rows: [
{id: "1", name: "Success"},
{id: "2", name: "Error"},
]
},
{
id: "Objects",
rows: [
{id: "1", name: "Object1"},
{id: "2", name: "Object2"},
]
},
{
id: "Groups",
rows: [
{id: "1", name: "Group1"},
{id: "2", name: "Group2"},
]
},
]
I need to create array with some condition. If my condition correctly I will push elements arr.rows.
Finally i want to get this structure:
[
{
Objects: "Object1",
Groups: "Group1"
},
{
Objects: "Object2",
Groups: "Group2"
}
]
I try to do like this
let sites = []
for (let el in arr) {
if (arr.id == "Objects") {
for (let item of el.rows) {
sites.push({Objects: item.name})
}
}
if (arr.id == "Groups") {
for (let item of el.rows) {
sites.Groups = item.name
}
}
}

You could map the wanted properties in new objects.
const
data = [{ id: "TaskStatuses", rows: [{ id: "1", name: "Success" }, { id: "2", name: "Error" }] }, { id: "Objects", rows: [{ id: "1", name: "Object1" }, { id: "2", name: "Object2" }] }, { id: "Groups", rows: [{ id: "1", name: "Group1" }, { id: "2", name: "Group2" }] }],
ids = ['Objects', 'Groups'],
result = data.reduce((r, { id, rows }) => ids.includes(id)
? rows.map(({ name }, i) => ({ ...r[i], [id]: name }))
: r,
[]
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

How to compare two array of objects and return the not matching object?

obj1 is the original object and obj2 is the changed object. I want to get the key , value pair and the type of all the changed object inside obje2 array of objects.
So, I need something like this where if "name" or "id" value is different in obj2 return the object along with the type.
changedObj = [
{
type:"mobile",
name:"Temple Runs",
id:2259
},
{
type:"pc",
name:"Pubgs",
id:222
}
]
obj1 = [
{
type: "mobile",
games: [
{
name: "Temple Run",
id: 2259,
},
{
name: "Subway Surfer",
id: 2271,
},
{
name: "Pubg",
id: 2272,
},
],
},
{
type: "pc",
games: [
{
name: "Pubg",
id: 222,
},
{
name: "Fortnite",
id: 2274,
},
{
name: "Nfs",
id: 2272,
},
],
},
];
obj2 = [
{
type: "mobile",
games: [
{
name: "Temple Runs",
id: 2259,
},
{
name: "Subway Surfer",
id: 2271,
},
{
name: "Pubg",
id: 2272,
},
],
},
{
type: "pc",
games: [
{
name: "Pubgs",
id: 222,
},
{
name: "Fortnite",
id: 2274,
},
{
name: "Nfs",
id: 2272,
},
],
},
];
How to achieve something like this ?
In order to find the difference, you will need to:
Map all of the updated platforms (type and games)
Filter the updated games and locate the original game by ID
Flat-map the games in each platform and include the type
const main = () => {
const delta = diff(changed, data);
console.log(delta);
};
const diff = (updated, original) =>
updated
.map(({ type, games }) => ({
type,
games: games
.filter(({ name, id }) => original
.find(platform => platform.type === type).games
.find(game => game.id === id)?.name !== name)
}))
.flatMap(({ type, games }) =>
games.map(({ name, id }) =>
({ name, id, type })));
const data = [{
type: "mobile",
games: [
{ name: "Temple Run", id: 2259 },
{ name: "Subway Surfer", id: 2271 },
{ name: "Pubg", id: 2272 }
],
}, {
type: "pc",
games: [
{ name: "Pubg", id: 222 },
{ name: "Fortnite", id: 2274 },
{ name: "Nfs", id: 2272 }
]
}];
const changed = [{
type: "mobile",
games: [
{ name: "Temple Runs", id: 2259 },
{ name: "Subway Surfer", id: 2271 },
{ name: "Pubg", id: 2272 }
],
}, {
type: "pc",
games: [
{ name: "Pubgs", id: 222 },
{ name: "Fortnite", id: 2274 },
{ name: "Nfs", id: 2272 }
]
}];
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

How to filter array key by another array number key

I have 2 array, first array structure is:
items: [
{
name: "a",
items: [
{ name: "jack" },
{ name: "jose" },
]
},
{
name: "b",
items: [
{ name: "lara" },
{ name: "jo" },
]
},
{
name: "c",
items: [
{ name: "andy" },
{ name: "hary" },
]
}
]
and the second array:
number: [
0: [0, 1],
1: [1],
2: [0]
]
How to filter "items" by "number" and How can such an output be obtained? (the best solution)
{["jack", "jole"],["jo"],["andy"]}
A few maps would do it:
the output you wish is not valid JS so I made a nested array
const arr1 = [{ name: "a", items: [{ name: "jack" }, { name: "jose" }, ] }, { name: "b", items: [{ name: "lara" }, { name: "jo" }, ] }, { name: "c", items: [{ name: "andy" }, { name: "hary" }, ] } ], numbers = [ [0, 1], [1], [0] ];
const res = numbers
.map((arr, i) => arr
.map(key => arr1[i].items[key].name)
)
console.log(res)
If your number variable has to be an Object.
let items = [
{
name: "a",
items: [{ name: "jack" }, { name: "jose" }]
},
{
name: "b",
items: [{ name: "lara" }, { name: "jo" }]
},
{
name: "c",
items: [{ name: "andy" }, { name: "hary" }]
}
];
let number = {
0: [0, 1],
1: [1],
2: [0]
};
let result = []
for (const [key, value] of Object.entries(number)){
let names = []
value.forEach(value => {
names.push(items[key].items[value].name)
})
result.push(names)
}
console.log(result)

Creating an array from 2 other arrays

I have two arrays of objects as shown below :
categories = [
{ name: "performance", id: 1 },
{ name: "understanding", id: 2 }
]
queries = [
{ name: "A", categoryId: "1" },
{ name: "B", categoryId: "1" },
{ name: "C", categoryId: "1" },
{ name: "D", categoryId: "2" }
]
Now, using these two arrays of objects, I need following array as a result:
process = [
{ category: "performance", query: [
{ name: "A" },
{ name: "B" },
{ name: "C" }
]},
{ category: "understanding", query: [{ name: "D" }] }
]
I have to match the categoryId with process's id and then create the above array.
I have tried the following way to solve this but could not get desired result.
const test = [];
categories.forEach((element) => {
const r = que.filter((res) => res.categoryId === element.id);
queries.forEach((rt) => {
if (rt.categoryId === element.id) {
test.push({
category: element.name,
query: [{
name: rt.name,
}],
});
}
});
});
Is this possible using any built in array methods in JavaScript?
Thanks in advance
Using Array.reduce, you can group queries by categoryId.
Based on that groupedBy object, using Array.map, you can get the result you want.
const categories = [{
name: "performance",
id: "1"
},{
name: "understanding",
id: "2"
}];
const queries = [{
name: "A",
categoryId: "1"
}, {
name: "B",
categoryId: "1"
}, {
name: "C",
categoryId: "1"
}, {
name: "D",
categoryId: "2"
}];
const groupByQueries = queries.reduce((acc, cur) => {
acc[cur.categoryId] ?
acc[cur.categoryId].push({ name: cur.name })
: acc[cur.categoryId] = [ { name: cur.name } ];
return acc;
}, {});
const result = categories.map(({ name, id }) => ({
category: name,
query: groupByQueries[id]
}));
console.log(result);
categories = [{name: "performance", id: 1},{name: "understanding", id: 2}];
queries = [{name: "A", categoryId: "1"}, {name: "B", categoryId: "1"}, {name: "C", categoryId: "1"}, {name: "D", categoryId: "2"}]
const test = [];
categories.forEach((element) => {
let temp = []
queries.map(item =>{
if(element.id.toString() === item.categoryId)
temp.push({name: item.name})
})
test.push({category:element.name,query:temp})
});
console.log(test)

use filter of Lodash/Javascript to get the filtered data

I have two array of objects.
const firstObj = [
{ Id: "1", Name: "Peter" },
{ Id: "2", Name: "John" },
{ Id: "12", Name: "jessy" },
];
const secondObj = [
{ Id: "1", Name: "Roa", original: { Id: "1" } },
{ Id: "2", Name: "John2", original: { Id: "2" } },
{ Id: "5", Name: "Rachel", original: { Id: "3" } },
];
Here, I am trying to filter data on the basis of Id and return the filtered firstObj
So, here firstObj has an entry { Id: "12", Name: "jessy" } this object whose Id does not match with the secondObj.original.Id so, firstObj will have the given result.
what I tried was
firstObj.filter(
firstObj,
secondObj.map((second) => {
return firstObj.Id === second.original.Id;
}),
);
But this does not work. Can any one help me out here , using Lodash or Js filter.
output would be -> [{"Id": "3", "Name": "jessy"}]
Is this what you are looking for?
const firstObj = [
{ Id: "1", Name: "Peter" },
{ Id: "2", Name: "John" },
{ Id: "12", Name: "jessy" },
];
const secondObj = [
{ Id: "1", Name: "Roa", original: { Id: "1" } },
{ Id: "2", Name: "John2", original: { Id: "2" } },
{ Id: "1", Name: "Rachel", original: { Id: "3" } },
];
const result = lodash.filter(firstObj, (firstItem) => {
return !lodash.some(secondObj, (secondItem) => {
return firstItem.Id === secondItem.original.Id;
});
});
Live: https://stackblitz.com/edit/js-addy5t?file=index.js
why use loadash for this. you can use native filter and find functions to achieve this
const filter = firstObj.filter(item => {
return secondObj.find(itm => itm.original.id === item.id)
});
You could use native method of Array.filter() and Array.some() to achieve the desired output.
Please check below working code snippet
ES6
const firstObj = [
{ Id: "1", Name: "Peter" },
{ Id: "2", Name: "John" },
{ Id: "12", Name: "jessy" },
],
secondObj = [
{ Id: "1", Name: "Roa", original: { Id: "1" } },
{ Id: "2", Name: "John2", original: { Id: "2" } },
{ Id: "1", Name: "Rachel", original: { Id: "3" } },
];
let result = firstObj.filter(({Id})=> !secondObj.some(item => item.original.Id === Id));
console.log(result)

How to sort nested array object using another nested array of on the basis of id?

My objective here is to convert the input array into the structure of the output array.
The input array and output array are shown below. If you observe carefully we can see that id is common in both the arrays and only title changes.
var output = [{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [{
id: "4",
title: 'title4',
children: [],
}, {
id: "5",
title: 'title5',
children: [{
id: "6",
title: 'title6',
children: [],
}, {
id: "7",
title: 'title7',
children: [],
}, {
id: "9",
title: 'title9',
children: [],
}]
}],
}
]
var input = [{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [{
id: "4",
title: 'title_changed',
children: [],
}, {
id: "5",
title: 'title_changed',
children: [],
children: [{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}
]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}
]
This function will look into the input array of corresponding element of output array on the . basis of id
let found;
function findTheKey(id, widget) {
let newObj = [...widget];
for (var key in newObj) {
if (newObj[key]["id"] == id) {
found = newObj[key];
break;
}
if (newObj[key].hasOwnProperty("children")) {
findTheKey(id, newObj[key].children);
}
}
return found;
}
This function will iterate over the output array and look for corresponding element in input array
function findAllObjectOnArray(output) {
let newObj = [...output];
for (let key in newObj) {
newObj[key] = {
...findTheKey(newObj[key]['id'], input),
children: newObj[key].children
};
if (newObj[key].hasOwnProperty("children")) {
findAllObjectOnArray(newObj[key].children, input);
}
}
return newObj;
}
var result = findAllObjectOnArray(output)
console.log(result)
The result is as expected on label 1 but as we move into nested object, it didn't changed.
Please suggest me something which will let it work. Any hint or solution is highly welcome ?
I've created a function fn that maps array elements to elemnts with property title = "title"+id and then recursively maps children nodes.
var output = [
{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [
{
id: "4",
title: 'title4',
children: [],
},
{
id: "5",
title: 'title5',
children: [
{
id: "6",
title: 'title6',
children: [],
},
{
id: "7",
title: 'title7',
children: [],
},
{
id: "9",
title: 'title9',
children: [],
}]
}],
}]
var input = [
{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [
{
id: "4",
title: 'title_changed',
children: [],
},
{
id: "5",
title: 'title_changed',
children: [],
children: [
{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}]
var fn = node =>
node && node.map( x =>
({
...x,
title: "title"+x.id,
children: fn(x.children)
})
)
var result = fn(output)
console.log(result)
A tip: Either stick to immutable (copy all objects) or modify it in-place. Things become really complicated when you mix the two unless you know what you are doing.
I'm not entirely sure if this is what you mean? It's hard to be sure if it works correctly because the title_changed strings are all the same.
I just added newObj[key].children = findAllObjectOnArray(newObj[key].children); so that the children property gets updated correctly (since you make a clone of the array on every call, so children doesn't get updated when you try to modify it by reference).
var output = [
{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [
{
id: "4",
title: 'title4',
children: [],
},
{
id: "5",
title: 'title5',
children: [
{
id: "6",
title: 'title6',
children: [],
},
{
id: "7",
title: 'title7',
children: [],
},
{
id: "9",
title: 'title9',
children: [],
}]
}],
}]
var input = [
{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [
{
id: "4",
title: 'title_changed',
children: [],
},
{
id: "5",
title: 'title_changed',
children: [],
children: [
{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}]
let found;
function findTheKey(id, widget) {
let newObj = [...widget];
for (var key in newObj) {
if (newObj[key]["id"] == id) {
found = newObj[key];
break;
}
if (newObj[key].hasOwnProperty("children")) {
findTheKey(id, newObj[key].children);
}
}
return found;
}
function findAllObjectOnArray(output) {
let newObj = [...output];
for (let key in newObj) {
newObj[key] = {
...findTheKey(newObj[key]['id'], input),
children: newObj[key].children
};
if (newObj[key].hasOwnProperty("children")) {
newObj[key].children = findAllObjectOnArray(newObj[key].children);
}
}
return newObj;
}
var result = findAllObjectOnArray(output)
console.log(result)

Categories