compare 2 object arrays and replace object by id - javascript

I have a multidimensional object array that I need to update by comparing to an object array. I flattened out the multidimensional array and did a nested for each loop. I am getting duplicate results and I can not figure out what I am doing wrong.
const newSections = [[{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}],[{"id":9141118,"name":" xzcxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"b6a78cf9-0de1-4465-bf7b-02b221330fcb"},{"id":9143204,"name":" xzcxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9ef10b9b-b143-48a2-8e4f-fc2fdad4788b"}]]
const section = [{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":"32","fut":0,"con":0,"tot":32,"storeTot":1,"variance":31,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}]
let myNewArray = [].concat.apply([], newSections)
let result = []
_.each(myNewArray, item => {
_.each(section, sec => {
if (item.uid === sec.uid) result.push(sec)
else result.push(item)
})
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

You can use find to avoid a nested loop (and that solves your duplication bug):
const newSections = [[{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}],[{"id":9141118,"name":" xzcxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"b6a78cf9-0de1-4465-bf7b-02b221330fcb"},{"id":9143204,"name":" xzcxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9ef10b9b-b143-48a2-8e4f-fc2fdad4788b"}]]
const section = [{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":"32","fut":0,"con":0,"tot":32,"storeTot":1,"variance":31,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}]
let myNewArray = [].concat.apply([], newSections)
let result = []
_.each(myNewArray, item => {
let newItem = section.find((sec) => item.uid === sec.uid)
result.push(newItem || item)
});
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

there is a logic error I think, you are loading elements of both array into your result array. you should skip pushing if (item.uid === sec.uid) result.push(sec) if ID matches.

Related

Find and Change specific item from an object array

I'm dealing with an array like
arr = [{id:'first',name:'John'},{id:'fifth',name:'Kat'},{id:'eitghth',name:'Isa'}]. Now i want to give condition to the array like if i get id 'fifth' in array, The array will change to
arr = [{id:'first',name:'John'},{id:'sixth',name:'Kat'},{id:'eitghth',name:'Isa'}]
Like just one part of an item is modified. How can i do that in js?
You can use Array.prototype.find to locate the entry, and then simply update its id attribute:
const arr = [{id:'first',name:'John'},{id:'fifth',name:'Kat'},{id:'eitghth',name:'Isa'}];
const entry = arr.find(item => item.id === 'fifth');
entry.id = 'sixth';
console.log(arr);
You can also use Array.prototype.findIndex to retrieve the index of the entry that you want to replace, and modify it accordingly:
const arr = [{id:'first',name:'John'},{id:'fifth',name:'Kat'},{id:'eitghth',name:'Isa'}];
const targetIndex = arr.findIndex(item => item.id === 'fifth');
arr[targetIndex].id = 'sixth';
console.log(arr);
However, the two methods above only help to find the first matching element. If you have multiple entries in the array with the ID of fifth, then you are better off using iteration:
const arr = [{id:'fifth',name:'Kat'},{id:'fifth',name:'Kat'},{id:'fifth',name:'Kat'}];
arr.forEach(item => {
if (item.id === 'fifth') {
item.id = 'sixth';
}
});
console.log(arr);

To remove duplicate among array of objects corresponding to the other key and value pair of object using javascript

Have an array of objects with object having two key and value pairs.
[{fruit:"apple",locale:"US"},
{fruit:"orange",locale:"US"},
{fruit:"banana",locale:"US"},
{fruit:"apple",locale:"US"},
{fruit:"orange",locale:"IT"},
{fruit:"apple",locale:"IT"},
{fruit:"banana",locale:"IT"},
{fruit:"orange",locale:"IT"}
{fruit:"apple",locale:"IT"}]
How to achieve
Fruit should not be duplicate within same locale,
Fruit can be same with different locales.
You can filter out the objects by matching the index value of current iteration. Something like this:
var data=[{fruit:"apple",locale:"US"},{fruit:"orange",locale:"US"},{fruit:"banana",locale:"US"},{fruit:"apple",locale:"US"},{fruit:"orange",locale:"IT"},{fruit:"apple",locale:"IT"},{fruit:"banana",locale:"IT"},{fruit:"orange",locale:"IT"},{fruit:"apple",locale:"IT"}];
var result = data.filter((e,i,self)=>self.findIndex(k=>k.fruit==e.fruit && k.locale==e.locale)==i);
console.log(result);
Or you can make use of Map:
var data=[{fruit:"apple",locale:"US"},{fruit:"orange",locale:"US"},{fruit:"banana",locale:"US"},{fruit:"apple",locale:"US"},{fruit:"orange",locale:"IT"},{fruit:"apple",locale:"IT"},{fruit:"banana",locale:"IT"},{fruit:"orange",locale:"IT"},{fruit:"apple",locale:"IT"}];
var result = [...new Map(data.map(k=>[`${k.fruit}|${k.locale}`, k])).values()];
console.log(result);
Try this..
obj = [{fruit:"apple",locale:"US"},
{fruit:"orange",locale:"US"},
{fruit:"banana",locale:"US"},
{fruit:"apple",locale:"US"},
{fruit:"orange",locale:"IT"},
{fruit:"apple",locale:"IT"},
{fruit:"banana",locale:"IT"},
{fruit:"orange",locale:"IT"}
{fruit:"apple",locale:"IT"}]
const uniqueArray = this.obj.filter((item, index) => {
const temp = JSON.stringify(item);
return index === this.obj.findIndex(obj => {
return JSON.stringify(obj) === temp;
});
});
console.log(uniqueArray);

while pushing the data in to arrays, not added in order

enter image description here
i need to push the data one after another, but here i am getting to add in disorder like last added array in to first.
for (var key in data[tabName + scoreBreakDown]) {
var values = data[tabName + scoreBreakDown][key];
var staticData = values[0];
var obj = [];
obj.push(staticData.CompanyName);
obj.push(staticData.Country_ORIG);
for (var value in values) {
if (addHeader) {
headersArray.push(values[value].AspectName);
weightArray.push(values[value].ScoreWeight);
}
obj.push(values[value].SPESGScore_ORIG);
}
addHeader = false;
dataArray.push(obj);
}
You can use array.map to map through an array and transform it into a new array in order.
In this example, we are just multiplying each value by 3, but the transformation is arbitrary.
let loop = (arr) => {
return arr.map(item => {
return item*3
})
}
console.log(loop([1,2,3,4,5]))
If you want to loop through an object in order this way, you can use Object.keys() this will return an array of the keys in the object.
let loop = (obj) => {
return Object.keys(obj).map(item => {
return `${item}: ${obj[item]}`
})
}
let obj = {
first_name:"John",
last_name:"Doe",
age:23
}
console.log(loop(obj))
So instead of using a for loop and an if statement to check a condition and push the data to the array after each iteration, you can use something Array.filter() to remove entries you don't want to push, and return them in order.
data = [
{header:true, value:"item1"},
{header:false, value:"item2"},
{header:true, value:"item3"},
]
let array = data.filter(item => {return item.header}).map(item => {
return item.value
})
console.log(array)

Get objects in array with duplicated values

I need to get elements from an array of objects where one of that object's properties (name in this case) is duplicated--in other words, appears in some other object in the array.
data
var data = [
{id:1, name:"sam", userid:"ACD"},
{id:1, name:"ram", userid:"SDC"},
{id:1, name:"sam", userid:"CSTR"}
];
i need to check all row and get all the array value where name property is duplicating.
the expected output:
[
{id:1, name:"sam", userid:"ACD"},
{id:1, name:"sam", userid:"CSTR"}
]
my code
Array.from(data).map(x => x.name)
but it is returning all the values.
The code should not create any performance issue because array will contain more than 500 rows.
Angular is a framework, not a language. There is no Angular in your problem.
Let me understand if I understood well. You have an array of objects and you want to keep all the elements that are duplicate and get rid of others, all right? You can try:
data.reduce((acc, value, i, arr) => {
if(acc.some(v => v.name === value.name)) return acc;
let filtered = arr.filter(v => v.name === value.name);
return filtered.length > 1 ? acc.concat(filtered) : acc;
}, []);
Or you can sort your array in first instance, in order to improve performance:
const sort = (a, b) => a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1;
let duplicates = [];
let sortedArray = data.sort(sort);
for(let i=0; i<sortedArray.length - 1; i++) {
if(sortedArray[i].name === sortedArray[i+1].name) {
duplicates.push(sortedArray[i], sortedArray[i+1]);
i++;
}
}
The brute force approach would be to filter the array to keep only those elements with duplicated names, as expressed by the filter function duplicateName.
// Is there more than one element in an array satisfying some predicate?
const hasMultiple = (arr, pred) => arr.filter(pred).length > 1;
// Is this element a duplicate in the context of the array?
const duplicateName = (elt, idx, arr) => hasMultiple(arr, e => e.name === elt.name);
// Test data.
var data = [
{id:1,name:"sam", userid:"ACD"},
{id:1,name:"ram", userid:"SDC"},
{id:1,name:"sam", userid:"CSTR"}
];
console.log(data.filter(duplicateName));
However, this is going to have poor performance (O(n^2)) in the case of many elements. To solve that problem, you're going to need to preprocess the array. We'll create an object with a property for each name, whose value is an array of all the elements in which that name occurs. This operation is usually called groupBy. Several popular libraries such as underscore will provide this for you. We'll write our own. After grouping, we will filter the object of groups to remove those with only one member.
// Group an array by some predicate.
const groupBy = (arr, pred) => arr.reduce((ret, elt) => {
const val = pred(elt);
(ret[val] = ret[val] || []).push(elt);
return ret;
}, {});
// Filter an object, based on a boolean callback.
const filter = (obj, callback) => Object.keys(obj).reduce((res, key) => {
if (callback(obj[key], key, obj)) res[key] = obj[key];
return res;
}, {});
// Remove groups with only one element.
const removeNonDups = groups => filter(groups, group => group.length > 1);
// Test data.
var data = [
{id:1,name:"sam", userid:"ACD"},
{id:1,name:"ram", userid:"SDC"},
{id:1,name:"sam", userid:"CSTR"}
];
console.log(removeNonDups(groupBy(data, elt => elt.name)));

reactJS adding a object array to and object within an object array

I got a response from a REST call, which returns and array with objects
response.data.steps
For example it looks like this
Now I need to add to each Child of this array an new Object Array.
What could be a smart solution for this problem?
Thanks.
In order to add a new array property to each item, you can simply do:
const steps = response.data.steps.map(step => ({
...step,
newObjectArray: [],
}))
you can usee Array.prototype.map() to do so
let result = response.data.steps.map(element => {
let ret = [element];
return ret;
});
let arr = [{a:1}, {a:2}, {a:3}];
arr = arr.map(element => {
let ret = [element];
return ret;
});
console.log(arr);

Categories

Resources