Find objects with duplicate value in an array [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 months ago.
Improve this question
I want all the name1 and name2 to be unique in every sub-array
[
{ id: 1, name1: a, name2: b },
{ id: 2, name1: c, name2: d },
{ id: 3, name1: e, name2: a }
],
[
{ id: 4, name1: t, name2: k },
{ id: 5, name1: j, name2: h },
{ id: 6, name1: z, name2: x },
],
]
In this example id-1 name1 and id-3 name2 have the value 'a', so I pushed id-3 to the next sub-array where there are no name1 and name2 matching id-3s name1 and name2.
[
{ id: 1, name1: a, name2: b },
{ id: 2, name1: c, name2: d },
],
[
{ id: 4, name1: t, name2: k },
{ id: 5, name1: j, name2: h },
{ id: 6, name1: z, name2: x },
{ id: 3, name1: e, name2: a },
],
]
If there's no such sub-array where id-3 name1 and name2 will be unique I want to create a new sub array and push id-3 into that.

You can build functions which determine whether a particular object is a "duplicate", then iterate your array, filtering out the duplicates and pushing them to the next entry in the array. If they are also a dupe in that entry, they will be pushed to the next entry, and so on...
const data = [
[
{ id: 1, name1: 'a', name2: 'b' },
{ id: 2, name1: 'c', name2: 'd' },
{ id: 3, name1: 'e', name2: 'a' }
],
[
{ id: 4, name1: 't', name2: 'k' },
{ id: 5, name1: 'j', name2: 'h' },
{ id: 6, name1: 'z', name2: 'x' },
],
]
// function to determine if an object's name1 or name2
// property exists in an other object with a lower index
const isdupe = (obj, idx, arr) =>
arr.findIndex(({ name1, name2 }, i) => [name1, name2].includes(obj.name1) || [name1, name2].includes(obj.name2)) != idx
const isnotdupe = (obj, idx, arr) => !isdupe(obj, idx, arr)
// iterate over the entries in the data array
for (let i = 0; i < data.length; i++) {
// find the duplicates in this array
let dupes = data[i].filter(isdupe)
// if there are any, add (concat) them to the next array
// (data[i+1] || []) will create a new entry if one doesn't exist
if (dupes.length) data[i+1] = (data[i+1] || []).concat(dupes)
// filter this array to only be non-duplicates
data[i] = data[i].filter(isnotdupe)
}
console.log(data)

I'm not quite sure what your asking for here, as you seem to grasp the concept, but i'm going to try and answer it, so appologies if its not a 100% fitting answer.
Every time that an item is added to the array, you could create a for statement that goes through every item on the array and checks if(item == new item) then it pushes it to array two, and repeats the checking process.
If you are asking for the specific commands related to it, a great resorce I use is https://www.w3schools.com
More specificaly for this question, https://www.w3schools.com/jsref/jsref_includes_array.asp

Related

Javascript sort array of objects based on another array

I have an array of objects I need to sort based on another array objects. This is the given array that needs to be sorted:
const arr1 = [
{
id: 21,
name: 'Joey',
vehicle: 'car'
},
{
id: 6,
name: 'Kevin'
vehicle: 'car'
},
{
id: 10,
name: 'Luis'
vehicle: 'van'
}
]
And this is the array that is in the proper order:
const arr2 = [
{
id: 6,
name: 'Kevin'
},
{
id: 21,
name: 'Joey'
},
{
id: 10,
name: 'Luis'
}
]
There is no specific order to arr2 its just the data that comes back from my db. I basically just need to put the ids in arr1 in the same order as thet are in arr2.
Ive tried using findIndex and sort but I am very confused
that ?
const arr1 =
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 10, name: 'Luis', vehicle: 'van' }
]
const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 10, name: 'Luis' }
]
// Arr1 ordered..
const arr1_ord = arr2.map(a2=> arr1.find(x=>x.id===a2.id))
console.log( arr1_ord )
.as-console-wrapper {max-height: 100%!important;top:0}
Also, if there are only 2 items in arr2 I still want those elements that are missing to be at the end of the sorted arr1. Would this solve that?
I add add another case : arr2 element doesn't have a arr1 same id
const arr1 =
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 12, name: 'George', vehicle: 'carriage' } // not in arr2
, { id: 10, name: 'Luis', vehicle: 'van' }
]
const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 88, name: 'none' } // not in arr1
, { id: 10, name: 'Luis' }
]
// Arr1 ordered..
const arr1_ord = arr2.reduce((res, {id},i,{[i+1]:next})=>
{
let a1 = arr1.find(x=>x.id===id)
if (a1) res.push(a1) // if exist in arr1
if (next) return res
else return [...res, arr1.filter(r=>!res.some(z=>z.id===r.id))] // add the missing elements
},[])
console.log( arr1_ord )
.as-console-wrapper {max-height: 100%!important;top:0}
Array.prototype.sort can take in a custom comparison function to sort however you'd like it to.
The function takes in two arguments (firstValue, secondValue)
If that function returns a positive value, then secondValue goes before the firstValue, if it's 0 or negative, then firstValue is sorted before secondValue. First/second value are from the array you are sorting. In your case, you are sorting based on a different array, but that is fine since you can do that in your function.
You can do:
arr1.sort((firstValue, secondValue) => {
return findIdInArr2(firstValue.id) - findIdInArr2(secondValue.id);
});
Where you would have to define findIdInArr2 to find the index in arr2, and you can use Array.prototype.findIndex to solve that problem. Where findIndex similarly takes in a function to find the index of something in an array.
function findIdInArr2(id) {
const foundIndex = arr2.findIndex(function(obj) {
return obj.id === id;
});
// If not found, this will be -1. But that would sort all
// unfound objects at the beginning of the array.
// To place these objects at the end of the array, it needs to
// return a number higher than the rest. So return infinity.
return (foundIndex === -1) ? Infinity : foundIndex;
}
note: findIndex is not available in IE, so you'd need to add a polyfill if you are planning on supporting IE.

JS/ES6/lodash find index of missing elements of two multidimensional arrays

Assuming that I have 2 multidimensional arrays of objects
const products = [
{
id: 1
name: 'lorem'
},
{
id: 3,
name: 'ipsum'
}
];
const tmp_products = [
{
id: 1
name: 'lorem'
},
{
id: 14,
name: 'porros'
},
{
id: 3,
name: 'ipsum'
},
{
id: 105,
name: 'dolor'
},
{
id: 32,
name: 'simet'
}
];
What is the correct way to find the missing indexes by id property?
I'm expecting an output such as [1,3,4] since those objects are not present in products
I found a similar question but applied to plain arrays:
Javascript find index of missing elements of two arrays
var a = ['a', 'b', 'c'],
b = ['b'],
result = [];
_.difference(a, b).forEach(function(t) {result.push(a.indexOf(t))});
console.log(result);
I'd like to use ES6 or lodash to get this as short as possible
You can use sets to do it quickly:
const productIds = new Set(products.map(v => v.id));
const inds = tmp_products
.map((v, i) => [v, i])
.filter(([v, i]) => !productIds.has(v.id))
.map(([v, i]) => i);
inds // [1, 3, 4]
You can use Array.prototype.reduce function to get the list of missing products' index.
Inside reduce callback, you can check if the product is included in products array or not using Array.prototype.some and based on that result, you can decide to add the product index or not.
const products = [
{
id: 1,
name: 'lorem'
},
{
id: 3,
name: 'ipsum'
}
];
const tmp_products = [
{
id: 1,
name: 'lorem'
},
{
id: 14,
name: 'porros'
},
{
id: 3,
name: 'ipsum'
},
{
id: 105,
name: 'dolor'
},
{
id: 32,
name: 'simet'
}
];
const missingIndex = tmp_products.reduce((acc, curV, curI) => {
if (!products.some((item) => item.id === curV.id && item.name === curV.name)) {
acc.push(curI);
}
return acc;
}, []);
console.log(missingIndex);
With lodash you could use differenceWith:
_(tmp_products)
.differenceWith(products, _.isEqual)
.map(prod => tmp_products.indexOf(prod))
.value()
This may not be great for performance, but it depends on how many items you have. With the size of your arrays this should perform ok.

Function question, angular typescript, match id values from 2 arrays to get the index from one of them

I have a two arrays, and I want to match their ID values and then get the index of that id in the second array. I know this sounds simple but I'm super new to the syntax, and I'm having a hard time picturing what this should look like. can anyone model that in simple terms?
example functionality:
var array1 = { id:2, name: 'preston'}
array2 = {
{
id: 1
name: 'john'
},
{
id: 2
name: 'bob'
}
Expected behavior
where both ids = 2, give index of array2.
returns 1
can anyone show me?
You can use findIndex on array2
Try this:
var array1 = {
id: 2,
name: 'preston'
}
var array2 = [{
id: 1,
name: 'john'
},
{
id: 2,
name: 'bob'
}
]
console.log(array2.findIndex(item => item.id === array1.id))
Or use indexOf with map if you want support for IE as well without polyfills.
var array1 = {
id: 2,
name: 'preston'
}
var array2 = [{
id: 1,
name: 'john'
},
{
id: 2,
name: 'bob'
}
]
console.log(array2.map(item => item.id).indexOf(array1.id))
Iterate over each item in array1 using forEach(). Find each item's index in array2 using findIndex().
var array1 = [{id:2, name: "preston"}];
var array2 = [{id: 1, name: "john" }, {id: 2, name: "bob" }];
array1.forEach(item => {
let index = array2.findIndex(obj => obj.id === item.id);
console.log(index);
});

Javascript sort an objects by another array [duplicate]

This question already has answers here:
How do I sort an array of objects based on the ordering of another array?
(9 answers)
Javascript - sort array based on another array
(26 answers)
Closed 4 years ago.
I have two arrays.
itemsArray =
[
{ id: 8, name: 'o'},
{ id: 7, name: 'g'},
{ id: 6, name: 'a'},
{ id: 5, name: 'k'},
{ id: 4, name: 'c'}
]
sortArray = [4,5]
How can i sort itemsArray by sortArray (lodash or pure), but i want to for this:
newArray =
[
{ id: 4, name: 'c'},
{ id: 5, name: 'k'},
{ id: 8, name: 'o'},
{ id: 7, name: 'g'},
{ id: 6, name: 'a'}
]
In a case like this where you want to sort on multiple levels, you need to sort them in descending order of importance inside your sorting function.
In this case we sort regularly on cases where both elements are either in or not in the sorting array.
var itemsArray = [
{ id: 8, name: 'o' },
{ id: 7, name: 'g' },
{ id: 6, name: 'a' },
{ id: 5, name: 'k' },
{ id: 4, name: 'c' }
];
var sortArray = [4, 5];
var sortedItemsArray = itemsArray.sort(function (a, b) {
if (sortArray.includes(a.id) == sortArray.includes(b.id)) { //both or neither are in sort array
return b.id - a.id;
}
else if (sortArray.includes(a.id)) { //only a in sort array
return -1;
}
else { //only b in sort array
return 1;
}
});
console.log(sortedItemsArray);
The above snippet could be expanded in multiple ways, but a popular approach is to separate it into several sorting steps.
var itemsArray = [
{ id: 8, name: 'o' },
{ id: 7, name: 'g' },
{ id: 6, name: 'a' },
{ id: 5, name: 'k' },
{ id: 4, name: 'c' }
];
var sortArray = [4, 5];
function sortId(a, b) {
return b.id - a.id;
}
function sortIdByList(a, b) {
if (sortArray.includes(a.id)) {
return -1;
}
if (sortArray.includes(b.id)) {
return 1;
}
return 0;
}
//TEST
var sortedItemsArray = itemsArray
.sort(sortId)
.sort(sortIdByList);
console.log(sortedItemsArray);
This pattern can be easier to maintain as each step is clearly labeled and the functions can be reused in other sorting cases.
The only downside to this pattern is that you end up iterating over the list multiple times, thus increasing the time to sort. Usually this is a non-issue but on very large lists this can be significant.
Sort by array index only
As the comments points out i misread the question, so my previous two sorting snippets doesn't necessarily give the desired result.
This version sorts only by id index in the sorting array:
var itemsArray = [
{ id: 8, name: 'o' },
{ id: 7, name: 'g' },
{ id: 6, name: 'a' },
{ id: 5, name: 'k' },
{ id: 4, name: 'c' }
];
var sortArray = [4, 5];
//TEST
var sortedItemsArray = itemsArray
.sort(function (a, b) {
//Calculate index value of a
var A = sortArray.indexOf(a.id);
if (A == -1) {
A = sortArray.length;
}
//Calculate index value of b
var B = sortArray.indexOf(b.id);
if (B == -1) {
B = sortArray.length;
}
//Return comparison
return A - B;
});
console.log(sortedItemsArray);
You could take the indices of the array for keeping the relative position and take the special items with a negative index to top for sorting.
Then sort the array by taking the indices.
var array = [{ id: 8, name: 'o' }, { id: 7, name: 'g' }, { id: 6, name: 'a' }, { id: 5, name: 'k' }, { id: 4, name: 'c' }],
sortArray = [4, 5],
indices = array.reduce((r, { id }, i) => (r[id] = i, r), {});
sortArray.forEach((id, i, { length }) => indices[id] = i - length);
array.sort(({ id: a }, { id: b }) => indices[a] - indices[b]);
console.log(array);
console.log(indices);
.as-console-wrapper { max-height: 100% !important; top: 0; }

how to check consecutive objects are same using underscore

var list = [
{name :a,id:1,index:1},
{name :a,id:1,index:2},
{name :b,id:2,index:3},
{name :c,id:3,index:4},
{name :b,id:2,index:5},
];
i want to avoid the above situation , here object having name = a
coming twice consecutively. But whereas object having name = b
is acceptable
i expect some buil it funtion which will find these type of objects. just like isNaN
tried with plain javascript but need function in underscore.
Downvoters pls comment before down voting :)
You coud use Array#every for the check. It stops the iteration if a result is false.
var list = [{ name: 'a', id: 1, index: 1 }, { name: 'a', id: 1, index: 2 }, { name: 'b', id: 2, index: 3 }, { name: 'c', id: 3, index: 4 }, { name: 'b', id: 2, index: 5 }],
notConsecutive = list.every(function (a, i, aa) {
return !i || aa[i - 1].name !== a.name;
});
console.log(notConsecutive);

Categories