How to sort/order multiple objects inside array? - javascript

This is my output:
const data = {
item : {
id: "1",
name: "aa",
group: [
{
id:"11",
order:0,
},
{
id:"33",
order:5,
},
{
id:"3",
order:1,
},
]
},
item2 : {
id: "2",
name: "aaa",
group: [
{
id:"111",
order:3,
},
{
id:"33",
order:1,
},
{
id:"3",
order:2,
},
]
}
}
I want to order my group object by order item. If it was an object, I could do it:
data.group.sort((a, b) => {
return a.order - b.order || a.order.localeCompare(b.order);
});
But it will override the elements and I will get only the lastest item. I believe that something else is missing to make it work the way I want.
This is the desired output:
const data = {
item : {
id: "1",
name: "aa",
group: [
{
id:"11",
order:0,
},
{
id:"3",
order:1,
},
{
id:"33",
order:5,
},
]
},
item2 : {
id: "2",
name: "aaa",
group: [
{
id:"33",
order:1,
},
{
id:"3",
order:2,
},
{
id:"111",
order:3,
},
]
}
}
How can i do that?

Try this code:
const data = {
item : {
id: "1",
name: "aa",
group: [
{
id:"11",
order:0,
},
{
id:"33",
order:5,
},
{
id:"3",
order:1,
},
]
},
item2 : {
id: "2",
name: "aaa",
group: [
{
id:"111",
order:3,
},
{
id:"33",
order:1,
},
{
id:"3",
order:2,
},
]
}
}
Object.keys(data).forEach(key => {
const item = data[key];
item.group = item.group.sort((a, b) => {
return a.order - b.order || a.order.localeCompare(b.order);
});
return item;
});
console.log(data);

Do this (CREDIT TO: flymaster)
Object.keys(dataINPT).forEach(key => {
const your = dataINPT[key];
your.group = your.group.sort((some, some2) => {
return some.order - some2.order || some.order.localeCompare(some2.order);
});
return your;
});
console.log(data);

Use the Object.values, forEach loop and apply sort.
Object.values(data).forEach(({ group }) =>
group.sort((a, b) => {
return a.order - b.order || a.order.localeCompare(b.order);
})
);
const data = {
item: {
id: "1",
name: "aa",
group: [
{
id: "11",
order: 0,
},
{
id: "33",
order: 5,
},
{
id: "3",
order: 1,
},
],
},
item2: {
id: "2",
name: "aaa",
group: [
{
id: "111",
order: 3,
},
{
id: "33",
order: 1,
},
{
id: "3",
order: 2,
},
],
},
};
Object.values(data).forEach(({ group }) =>
group.sort((a, b) => {
return a.order - b.order || a.order.localeCompare(b.order);
})
);
console.log(data);

Related

Filter 2 arrays to check if parent child

I have first array -
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
And 2nd Array Object -
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
From parent array I want to select all those elements whose id matches with childid from child array.
I tried -
parent.filter(x=>x.id==child.each(y=>y.childid))
But its not working
You can use some() to do it
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
let result = parent.filter(p => child.some(a => a.childid == p.id ))
console.log(result)
using Flatmap and filter ...
let parent = [{
id: 1,
value: "ABC",
},
{
id: 2,
value: "DEF",
},
{
id: 3,
value: "GHI",
},
{
id: 4,
value: "JKL",
},
{
id: 5,
value: "MNO",
},
{
id: 6,
value: "PQR",
},
]
let child = [{
childid: 1,
value: "ABC",
},
{
childid: 2,
value: "DEF",
},
{
childid: 10,
value: "GHI",
},
]
const res = parent.flatMap(x => child.filter(y => y.childid === x.id))
console.log(res)
This would work
parent.filter(p => child.some(c => c.childid === p.id))
Wat happens is
For each element in parent array, find the corresponding element in the child array
If it exists the filter will see it as truthy and keep the parent element, if not it will be falsy and filter wil discard it
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
const filterResult = parent.filter(x => child.some(y => y.childid == x.id))
You can use a reduce function along with a forEach to loop through the child elements and compare against the parent.
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
});
return acc;
}, []);
console.log(result); // [{"id":1,"value":"ABC"},{"id":2,"value":"DEF"}]
const parents = [{
id: 1,
value: 'ABC',
},
{
id: 2,
value: 'DEF',
},
{
id: 3,
value: 'GHI',
},
{
id: 4,
value: 'JKL',
},
{
id: 5,
value: 'MNO',
},
{
id: 6,
value: 'PQR',
},
];
const children = [{
childid: 1,
value: 'ABC',
},
{
childid: 2,
value: 'DEF',
},
{
childid: 10,
value: 'GHI',
},
];
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
return acc;
});
return acc;
}, []);
console.log(result);
MDN Reduce

How to get all possible ways of passing the quiz

The quiz is implemented in such a way that questions are displayed depending on the user's choice. I need to implement the testing functionality of the questionnaire. After passing in the console should have the same structure as I have provided below. Now my script produces a slightly different structure, not the same as in the example. Example of my code:
const questions = [
{
id: "1",
question: "q1",
answer_1: {
text: "a1",
next_question: "2",
},
answer_2: {
text: "a2",
next_question: "3",
},
},
{
id: "2",
question: "q2",
answer_1: {
text: "a1/a2",
next_question: "",
},
},
{
id: "3",
question: "q3",
answer_1: {
text: "a1",
next_question: "",
},
answer_2: {
text: "a2",
next_question: "4",
},
},
{
id: "4",
question: "q4",
answer_1: {
text: "a1/a2",
next_question: "",
},
},
];
const newQuestionObj = {};
const getAllPath = (arr) => {
const treeStructure = arr.forEach((item) => {
newQuestionObj[item.id] = {
...item,
children: [
...Object.keys(item)
.filter((k) => k.includes("answer"))
.map((k) => ({ ...item[k] })),
],
};
});
const createBranches = ({ question, children }) =>
children.map(({ text, next_question }) =>
next_question.length === 0
? { [question]: text }
: createBranches(newQuestionObj[next_question]).map((obj) => ({
[question]: text,
...obj,
}))
);
return createBranches(newQuestionObj[arr[0].id]);
};
let result = {
path: {
list: getAllPath(questions),
},
};
console.log(result);
Desired result to get:
{
"paths":{
"list":[
[
{
"q1":"a1"
},
{
"q2":"a1/a2"
}
],
[
{
"q1":"a2"
},
{
"q3":"a1"
}
],
[
{
"q1":"a2"
},
{
"q3":"a2"
},
{
"q4":"a1/a2"
}
]
]
}
}

How know the value of property of object in javascript?

I have this object:
var x= {
"data": {
"getLand": {
"id": "xxx",
"bid": [{
"result": "ON",
"buyer": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "202",
"value": 1
}]
},
{
"result": "CANCEL",
"buyer": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "202",
"value": 15
}]
}
]
}
}
}
How can i know is result === "ON" && username == "Dis" ?
I tried with this:
for (var key in x.data.getLand.bid) {
if((x.data.getLand.bid[key].result === 'ON') && (x.data.getLand.bid[key].buyer.username.toUpperCase() === 'DIS')){
console.log(x.data.getLand.bid[key]);
}
}
it gives me some problems .... sometimes it works and sometimes it doesn't. Would you be kind enough to show me another way?
You can utilize the ES6 array function forEach to loop through the array items.
const x = { data: { getLand: { id: "xxx", bid: [ { result: "ON", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 1, }, ], }, { result: "CANCEL", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 15, }, ], }, ], }, }, }
const bidList = x.data.getLand.bid
bidList.forEach((bid, index) => {
if (bid.result === 'ON' && bid.buyer.username.toUpperCase() === 'DIS') console.log(index, bid)
})
You can do this with filter and forEach loop.
like this:
var x = { data: { getLand: { id: "xxx", bid: [ { result: "ON", buyer: { username: "Dis" }, offerSet: [{ createdStr: "202", value: 1 }] }, { result: "CANCEL", buyer: { username: "Dis" }, offerSet: [{ createdStr: "202", value: 15 }] } ] } } };
x.data.getLand.bid
.filter(
({ result, buyer: { username } }) => result === "ON" || username === "Dis"
)
.forEach((el, id) => console.log(el, id));
An example with for...of
var x = { data: { getLand: { id: "xxx", bid: [ { result: "ON", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 1, }, ], }, { result: "CANCEL", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 15, }, ], }, ], }, }, };
for (const item of x.data.getLand.bid) {
if (item.result === "ON" && item.buyer.username.toUpperCase() === "DIS") {
console.log(item);
}
}
Edit:
If you need the index, you can use forEach.
var x = { data: { getLand: { id: "xxx", bid: [ { result: "ON", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 1, }, ], }, { result: "CANCEL", buyer: { username: "Dis", }, offerSet: [ { createdStr: "202", value: 15, }, ], }, ], }, }, };
x.data.getLand.bid.forEach((item, i) => {
if (item.result === "ON" && item.buyer.username.toUpperCase() === "DIS") {
console.log(i);
console.log(item);
}
});

filter object value using node js

Is there any way i can filter values which are present inside Object
[
{
id: "1",
name:"animal_image.jpg"
},
{
id: "2",
name:"fish_image.jpg"
},
{
id: "3",
name:"animal_doc.txt"
},{
id: "4",
name:"fish_doc.txt"
},
{
id: "4",
name:"flower_petals.jpg"
},
{
id: "5",
name:"plant_roots.jpg"
},
{
id: "6",
name:"human_image.jpg"
},
]
i want to filter all the name which contain_image.jpg so output look like this
output=
[ "human_image.jpg",
"anima_image.jpg",
"fish_image.jpg"
]
In this code snippet filtredData is an array of objects where the name includes _image.jpg and output is just an array of names containing _image.jpg
const data = [
{
id: "1",
name: "animal_image.jpg"
},
{
id: "2",
name: "fish_image.jpg"
},
{
id: "3",
name: "animal_doc.txt"
}, {
id: "4",
name: "fish_doc.txt"
},
{
id: "4",
name: "flower_petals.jpg"
},
{
id: "5",
name: "plant_roots.jpg"
},
{
id: "6",
name: "human_image.jpg"
},
]
const filtredData = data.filter(el => el.name.includes("_image.jpg"));
console.log(filtredData);
const output = filtredData.map(el => el.name);
console.log(output);
filter & map
const output = arr
.filter(x => x.name.endsWith('_image.jpg'))
.map(x => x.name);

Setting array keys dynamically based on length

Given an array in this format:
[
[{
name: "name",
value: "My-name"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test.com"
},
{
name: "comment",
value: "my-comment"
}
],
[{
name: "name",
value: "My-name2"
},
{
name: "qty",
value: "3"
},
{
name: "url",
value: "test2.com"
}
],
[{
name: "name",
value: "My-name3"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test3.com"
},
{
name: "comment",
value: "my-comment3"
}
]
]
I'm looking to switch that to:
[
[
{ name: "My-name" },
{ qty: "1" },
{ url: "test.com" },
{ comment: "my-comment", }
],[
{ name: "My-name2" },
{ qty: "3" },
{ url: "test2.com",
],[
{ name: "My-name3", },
{ qty: "1", },
{ url: "test3.com", },
{ comment: "my-comment3", }
]
]
In other words, swapping out the array keys but maintaining the object structure within each array element.
I've tried looping over each element and can swap the keys out using something like:
newArray[iCount][item.name] = item.value;
However I'm then struggling to preserve the object order. Note that the comment field may or may not appear in the object.
With Array.map() function:
var arr = [
[{name:"name",value:"My-name"},{name:"qty",value:"1"},{name:"url",value:"test.com"},{name:"comment",value:"my-comment"}],
[{name:"name",value:"My-name2"},{name:"qty",value:"3"},{name:"url",value:"test2.com"}],
[{name:"name",value:"My-name3"},{name:"qty",value:"1"},{name:"url",value:"test3.com"},{name:"comment",value:"my-comment3"}]
],
result = arr.map(function(a){
return a.map(function(obj){
var o = {};
o[obj.name] = obj.value
return o;
});
});
console.log(result);
Check my moreBetterOutput value. I think will be better.
If you still need a result like your example in the question then you can check output value.
const input = [
[
{
name:"name",
value:"My-name"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test.com"
},
{
name:"comment",
value:"my-comment"
}
],
[
{
name:"name",
value:"My-name2"
},
{
name:"qty",
value:"3"
},
{
name:"url",
value:"test2.com"
}
],
[
{
name:"name",
value:"My-name3"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test3.com"
},
{
name:"comment",
value:"my-comment3"
}
]
]
const output = input.map(arr => arr.map(obj => ({[obj.name]: obj.value})))
const moreBetterOutput = output.map(arr => arr.reduce((acc, item, index) => {
acc[Object.keys(item)[0]] = item[Object.keys(item)[0]];
return acc;
}, {}) )
//console.log(output);
console.log(moreBetterOutput);
Another map function:
const result = array.map( subarray =>
Object.assign(...subarray.map( ({name, value}) => ({ [name] : value }) ))
);

Categories

Resources