I am trying to retrieve result from 2 array - javascript

i am trying to filter first array based on second array text , but i am not getting how to update the count filter to the first array from second array.
First Array:
var firstArray =[{text:"India",count:1,checked:true},
{text:"America",count:2,checked:false},
{text:"Uk",count:1,checked:true}];
Second Array:
var secondArray=[
{text:"India",count:1,checked:false},
{text:"America",count:1,checked:false},
{text:"Uk",count:1,checked:false}
];
Code:
var result=firstArray.filter(o1 => secondArray.some(o2 => o1.text === o2.text));
Result which i am currently getting:
var result=[
{text:"India",count:1,checked:true},
{text:"America",count:2,checked:false},
{text:"Uk",count:1,checked:true}
];
Result which i am trying to get is below:
var result=[
{text:"India",count:1,checked:true},
{text:"America",count:1,checked:false},
{text:"Uk",count:1,checked:true}
];
Thanks for the help!!!

You can map the first array and pick the count from second array like this
var firstArray = [
{ text: "India", count: 1, checked: true },
{ text: "America", count: 2, checked: false },
{ text: "Uk", count: 1, checked: true },
];
var secondArray = [
{ text: "India", count: 1, checked: false },
{ text: "America", count: 1, checked: false },
{ text: "Uk", count: 1, checked: false },
];
firstArray
.map((x) => {
const tmp = secondArray.find((y) => y.text === x.text);
return tmp ? { ...x, count: tmp.count } : null
})
.filter(Boolean);

A possible solution would like as below
var firstArray = [{
text: "India",
count: 1,
checked: true
},
{
text: "America",
count: 2,
checked: false
},
{
text: "Uk",
count: 1,
checked: true
}
];
var secondArray = [{
text: "India",
count: 1,
checked: false
},
{
text: "America",
count: 1,
checked: false
},
{
text: "Uk",
count: 1,
checked: false
}
];
var result = firstArray.map(o1 => {
const o2 = secondArray.find(o2 => o1.text === o2.text);
if (!o2) return;
return { ...o1,
count: o2.count
}
}).filter(o1 => !!o1);
console.log(result)

This solution will merge the two arrays to get the desidered result (as deduced from the answer)
var firstArray =[{text:"India",count:1,checked:true},
{text:"America",count:2,checked:false},
{text:"Uk",count:1,checked:true}];
var secondArray=[
{text:"India",count:1,checked:false},
{text:"America",count:1,checked:false},
{text:"Uk",count:1,checked:false}
];
const newArray = firstArray.map((el1) => {
let sameElList = secondArray.filter((el2) => el2.text === el1.text);
let sameEl = sameElList.length > 0 && sameElList.pop();
if(!sameEl){
return el1;
}
el1.count = Math.min(el1.count, sameEl.count);
el1.checked = el1.checked || sameEl.checked;
return el1;
});
console.log(newArray);

Related

get array of object value and nested array of object value

I've this nested array of object array:
const items = [
{
id: 1,
name: 'banana',
selected: true,
},
{
id: 2,
subItems: [
{
id: '2a',
name: 'apple',
selected: true,
},
{
id: '2b',
name: 'orange',
selected: false,
},
],
},
{
id: 3,
name: 'watermalon',
selected: true,
},
{
id: 4,
name: 'pear',
selected: false,
},
]
How can I get the ids base on selected property?
I manage to get the first level, I've tried
const selectedItemId = items.map(item => item.selected && item.id).filter(Boolean)
but how can I select the ids which is in the subItems? I expect the result to be [1, '2a', 3]
Flatten the array first. Be careful of using && item.id inside the mapper because that'll mean that falsey IDs (like 0, which is a reasonable starting number in some schemes) will be excluded.
const items=[{id:1,name:"banana",selected:!0},{id:2,subItems:[{id:"2a",name:"apple",selected:!0},{id:"2b",name:"orange",selected:!1}]},{id:3,name:"watermalon",selected:!0},{id:4,name:"pear",selected:!1}];
const output = items
.flatMap(item => [item].concat(item.subItems ?? []))
.filter(item => item.selected)
.map(item => item.id);
console.log(output);
You can recursively traverse all the items and select the items that have selected set to true.
const items = [
{ id: 1, name: "banana", selected: true },
{
id: 2,
subItems: [
{ id: "2a", name: "apple", selected: true },
{ id: "2b", name: "orange", selected: false },
],
},
{ id: 3, name: "watermalon", selected: true },
{ id: 4, name: "pear", selected: false },
];
function getSelectedItems(items, selectedItems = []) {
for (let item of items) {
if (item.subItems) {
getSelectedItems(item.subItems, selectedItems);
} else if (item.selected) {
selectedItems.push(item.id);
}
}
return selectedItems;
}
console.log(getSelectedItems(items));
let newArray = [];
items.forEach(i=>{
if(i.selected){
newArray.push(i.id)
}
if(i.subItems){
i.subItems.forEach(j=>{
if(j.selected){
newArray.push(j.id)
}
})
}
});
so this is bit lengthy. with 2 map loops
You can do:
const items=[{id:1,name:"banana",selected:!0},{id:2,subItems:[{id:"2a",name:"apple",selected:!0},{id:"2b",name:"orange",selected:!1}]},{id:3,name:"watermalon",selected:!0},{id:4,name:"pear",selected:!1}]
const output = items
.reduce((a, c) => [...a, c, ...(c.subItems || [])], [])
.filter(o => o.selected)
.map(({ id }) => id)
console.log(output)
Checking if a subItems array exsist in the item and recusively calling a function to extract selected Items will solve the issue.
function extractSubItems (items){
var selectItemsId = [];
selectItemsId = selectItemsId + items.map(item => {
if (item.selected===true){
return item.id;
}
if (item.subItems){
return extractSubItems(item.subItems);
}
}).filter(Boolean);
return selectItemsId
}
You can use Array#reduce in a nested fashion as follows:
const items = [ { id: 1, name: 'banana', selected: true, }, { id: 2, subItems: [ { id: '2a', name: 'apple', selected: true, }, { id: '2b', name: 'orange', selected: false, }, ], }, { id: 3, name: 'watermalon', selected: true, }, { id: 4, name: 'pear', selected: false, }, ],
output = items
.reduce(
(prev, {id,selected,subItems}) =>
subItems ?
selected ?
[...prev,id,...subItems.reduce( (p, {id:ID,selected:SEL}) => SEL ? [...p,ID] : p, [] )] :
[...prev,...subItems.reduce( (p, {id:ID,selected:SEL}) => SEL ? [...p,ID] : p, [] )] :
selected ?
[...prev,id] :
prev, []
);
console.log( output )
1 - Loop through items array
2 - if there is no subItems array then find the id of the item using condition
3 - if there is a subItems array then loop through that and find the id using condition
const result = []
items.map(item=>{
item.subItems ?
item.subItems.map(sub=>{
sub.selected && result.push(sub.id)
})
: item.selected && result.push(item.id)
})
console.log(result) // [1, "2a", 3]
This also works:
var ids = [
... items.filter(
it => it.selected || (it.subItems && it.subItems.some( sub => sub.selected ))
)
.map( it =>
it.subItems
? it.subItems.filter( it_sub => it_sub.selected ).map( it_sub => it_sub.id )
: [it.id]
)
].flat()
With resursive of subItems :
const items=[
{id:1,name:"banana",selected:!0},
{id:2,subItems:
[
{id:"2a",name:"apple",selected:!0},
{id:"2b",name:"orange",selected:!1},
{id:"2c",subItems:
[
{id:"2c1",name:"apple1",selected:!0},
{id:"2c1",name:"orange1",selected:!1}
]
},
]
},
{id:3,name:"watermalon",selected:!0},
{id:4,name:"pear",selected:!1}
];
const getSubItem = (obj) => {
let result = !obj.hasOwnProperty('subItems') ? [obj] : obj.subItems.reduce((res, item) => {
return res.concat(getSubItem(item))
}, [])
return result.filter(item => item.selected)
}
const result = items.reduce((res, item) => {
let subItem = getSubItem(item)
return res.concat(getSubItem(item))
}, [])
console.log(result)

How to change the nested array object to object depending on type in javascript

I would like to know how to change nested array object to object depending on key in javascript
I have objects obj1 and obj2, depending on key item type change the object.
function changeObj(obj){
let result = obj.reduce(function (acc, item) {
if(item.items.trim() !== "" && item.key.trim() !== ""){
acc[item.key] = item.items
return acc
}
return acc
}, {});
return result;
}
let result = this.changeObj(obj2)
var obj1 = [
{ id:0, items:["SG","AU"], count: 2, key:"countries"},
{ id:1, items:["finance"], count: 3 key:"info"}
]
var obj2 = [
{ id:0, items: "SG", key: "country"},
{ id:1, items: "details", key: "info"}
]
Expected Output:
// if items key is array
{
fields: {
countries: ["SG","AU",2],
info: ["finance",3]
}
}
//if items key is string
{
fields: {
country: "SG",
info: "details"
}
}
I think the reason your code is not running is because the wrong format of your objects (1 and 2). Your code is okay except the condition because trim() only works on string type so it errors on array. Try this code snippet
function changeObj(obj){
let result = obj.reduce(function (acc, item) {
acc[item.key] = item.items;
return acc;
}, {});
return result;
}
var obj1 = [
{ id:0, items:["SG","AU"], count: 2, key:"countries"},
{ id:1, items:["finance"], count: 3, key:"info"}
]
var obj2 = [
{ id:0, items: "SG", key: "country"},
{ id:1, items: "details", key: "info"}
]
console.log(changeObj(obj1));
const changeObj = obj =>
obj.reduce((acc, item) => {
if (Array.isArray(item.items)) {
acc[item.key] = [...item.items, item.count];
} else {
acc[item.key] = item.items;
}
return acc;
}, {});
var obj1 = [
{ id: 0, items: ['SG', 'AU'], count: 2, key: 'countries' },
{ id: 1, items: ['finance'], count: 3, key: 'info' }
];
var obj2 = [
{ id: 0, items: 'SG', key: 'country' },
{ id: 1, items: 'details', key: 'info' }
];
console.log(changeObj(obj1));
console.log(changeObj(obj2));
or cleaned up even more
const changeObj = obj =>
obj.reduce((acc, { items, key, count }) => {
Array.isArray(items) ? (acc[key] = [...items, count]) : (acc[key] = items);
return acc;
}, {});
var obj1 = [
{ id: 0, items: ['SG', 'AU'], count: 2, key: 'countries' },
{ id: 1, items: ['finance'], count: 3, key: 'info' }
];
var obj2 = [
{ id: 0, items: 'SG', key: 'country' },
{ id: 1, items: 'details', key: 'info' }
];
console.log(changeObj(obj1));
console.log(changeObj(obj2));

How to compare two array with object?

I compare id with two array with object.
Here is my function:
array1 = [
{ id: 1 },
{ id: 2 },
{ id: 3 }
];
array2 = [
{ id: 1 },
{ id: 2 },
{ id: 3 }
];
const compareFunction = (array1, array2) => {
array2.map((allValue) => {
array1.map((value) => {
allValue.selected = value.id === allValue.id;
});
})
return array2;
}
I think I will get the array2 like
[{ id: 1, selected: true }, { id: 2, selected: true },{ id: 3, selected: true }]
but actually array2 become
[{ id: 1, selected: false }, { id: 2, selected: false },{ id: 3, selected: true }]
Only the last array argument selected become true.
Which step was wrong ? Thanks.
Convert the 2nd array to a Set of id values. Iterate the 1st array with a Array.map() and create a new object for each item, by spreading the current object, and adding the selected value. To get the selected value check if the Set contains that current item id.
const array1 = [{ id: 1 },{ id: 2 },{ id: 3 }];
const array2 = [{ id: 1 },{ id: 2 },{ id: 3 }];
const a2Set = new Set(array2.map(o => o.id))
const result = array1.map(o => ({ ...o, selected: a2Set.has(o.id) }))
console.log(result)
checkout this :
array1 = [{ id: 1 },{ id: 2 },{ id: 3 }];
array2 = [{ id: 1 },{ id: 2 },{ id: 3 }];
const compareFunction = (array1, array2) => {
const result = [];
array2.forEach(arr2item => {
let selected = false;
for(let arr1item of array1){
selected = arr1item.id === arr2item.id;
if(selected)break;
}
result.push({id : arr2item.id , selected : selected});
});
return result;
}
console.log(compareFunction(array1 , array2));

Need to remove duplicates in an Array of Objects - grabing the higher value of a key

I have an array of Objects with duplicates. I want to remove those duplicates but need to get the "duplicate" where a third key has the higher value.
Tried this solutions: Remove duplicates from an array of objects in JavaScript
but this gives me always the first duplicate and I need to check which has the higher value of third keys.
let testArray = [
{ id: 1, value: "test1", value1: 1 },
{ id: 2, value: "test2", value1: 1 },
{ id: 1, value: "test3", value1: 5 }
];
let filtered = testArray.reduce((accumulator, current) => {
if (!accumulator.find(({ id }) => id === current.id)) {
accumulator.push(current);
}
return accumulator;
}, []);
console.log(filtered);
/*
Result is:
[ { id: 1, value: 'test1', value1: 1 },
{ id: 2, value: 'test2', value1: 1 } ]
Result desired:
[ { id: 1, value: 'test1', value1: 5 },
{ id: 2, value: 'test2', value1: 1 } ]
*/
I expect a result like:
[ { id: 1, value: 'test1', value1: 1 },
{ id: 2, value: 'test2', value1: 5 } ]
of the testArray
You could search for the index and if valid check the value and update the array if the value is greater.
let testArray = [
{ id: 1, value: "test1", value1: 1 },
{ id: 2, value: "test2", value1: 1 },
{ id: 1, value: "test3", value1: 5 }
];
let filtered = testArray.reduce((accumulator, current) => {
let index = accumulator.findIndex(({ id }) => id === current.id)
if (index === -1) {
accumulator.push(current);
} else if (accumulator[index].value1 < current.value1) {
accumulator[index] = current;
}
return accumulator;
}, []);
console.log(filtered);
Simply maintain a map corresponding to each id, and update the map if the existing value is less than new value, Object.values() on the map will give you the desired result:
let testArray = [ { id: 1, value: "test1", value1: 1 }, { id: 2, value: "test2", value1: 1 }, { id: 1, value: "test3", value1: 5 } ];
let filtered = Object.values(testArray.reduce((acc, curr)=>{
acc[curr.id] = acc[curr.id] && acc[curr.id].value1 > curr.value1 ? acc[curr.id] : curr;
return acc;
},{}));
console.log(filtered);

Get objects having id in 1st array as same as id in objects of other array in java script

I have 2 arrays of objects.
They are
array1 = [{
id:2,
name:"person2"
},{
id:3,
name:"person3"
},
{
id:4,
name:"person4"
},
{
id:5,
name:"person5"
},
];
array2 = [
{
empId:2,
isdeleted:false
},
{
empId:4,
isdeleted:false
},
{
empId:3,
isdeleted:true
}];
I need the object from array1 whose id matches with empId of array2 and having isdeleted false. Thanks in advance.
You can use filter and some like this:
let array1 = [{
id: 2,
name: "person2"
}, {
id: 3,
name: "person3"
},
{
id: 4,
name: "person4"
},
{
id: 5,
name: "person5"
},
];
let array2 = [{
empId: 2,
isdeleted: false
},
{
empId: 4,
isdeleted: false
},
{
empId: 3,
isdeleted: true
}
];
let filteredArray = array1.filter(a => array2.some(b => b.empId === a.id && !b.isdeleted));
console.log(filteredArray);
Try
let result = [];
array1.forEach(function(element1){
array2.forEach(function(element2){
if (element1.id === element2.empId && !element2.isdeleted){
result.push(element);
}
});
});
console.log(result);
You can use Array.filter() together with find() to find the object with that condition in array2:
var array1 = [{
id: 2,
name: "person2"
}, {
id: 3,
name: "person3"
},
{
id: 4,
name: "person4"
},
{
id: 5,
name: "person5"
},
];
var array2 = [{
empId: 2,
isdeleted: false
},
{
empId: 4,
isdeleted: false
},
{
empId: 3,
isdeleted: true
}
];
var res = array1.filter((obj1)=>{
var exist = array2.find((obj2)=> (obj1.id == obj2.empId && !obj2.isdeleted));
return exist;
});
console.log(res);
You could try something like this:
let array1 = [
{ id:2, name:"person2"},
{ id:3, name:"person3"},
{ id:4, name:"person4"},
{ id:5, name:"person5"}
];
let array2 = [
{ empId:2, isdeleted:false},
{ empId:4, isdeleted:false},
{ empId:3, isdeleted:true}
];
let result = array1.reduce((output, item) => {
if (array2.find((item2) => !item2.isdeleted && item.id === item2.empId)) output.push(item);
return output;
}, []);
console.log(result);

Categories

Resources