Reducing a 2D array taking into account another 2D array - javascript

I have two 2D arrays with identical elements but in a different order. I want to filter one taking into account if it already exists in the second array.
Examples of both arrays:
const firstArray = [['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['43452341','2020-4-28']] // there are like 40 arrays inside, not sorted
const secondArray = [['34347896', '2020´4-30'],['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['45892916','2020-4-28']] // there are like 300 arrays inside, not sorted
I want to eliminate the arrays of the "secondArray" that have the first index repeated in the "firstArray".
secondArray =[['34347896', '2020´4-30'], ['45892916','2020-4-28']]
I tried several things, I know that the most useful action is to use .reduce but it seems that I cannot make it work.
const notPosted = secondArray.reduce((a, b) => {
if (!firstArray[a[0]]) a.different.push(b);
return a;
}, {different: []});
Thanks!

I dont know which one is faster:
const arr1 = [['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['43452341','2020-4-28']]
const arr2 = [['34347896', '2020´4-30'],['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['45892916','2020-4-28']];
//First solution:
console.log("1) ",arr2.filter(e=>!arr1.some(e2=>JSON.stringify(e2)==JSON.stringify(e))))
//Second:
console.log("2) ",arr2.filter(e=>!arr1.some(e2=>e[0]==e2[0]&&e[1]==e2[1])))

You could convert your 2D array into an object with the zero index of each nested array being the key, and the first index being the value. (i.e. you already have your array in the perfect form for this [[key, val], [key, val], ...])
This is easy with Object.fromEntries(firstArray);
Then you call a simple filter function on your second array and return only those that have a key that is not in the object (lookups of keys in an object are fast - hash tables)
// there are like 40 arrays inside, not sorted
const firstArray = [['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['43452341','2020-4-28']]
// there are like 300 arrays inside, not sorted
const secondArray = [['34347896', '2020´4-30'],['45614726','2020-4-28'],['45610125','2020-4-28'],['45880944','2020-4-28'],['45892916','2020-4-28']];
const firstObj = Object.fromEntries(firstArray);
const secondFiltered = secondArray.filter(([key,val]) => !firstObj.hasOwnProperty(key));
console.log(secondFiltered);

Related

updating value of object inside of array based on id of different object in different array in react

if I have an array like this:
const[arr,setArr] = React.useState([
{label:"dummy01",id:2},
{label:"dummy02",id:5},
])
is there anyway to update arr with such array:
const newArray = [{label:'dummy Altered01',id:2},{label:'different',id:10},{label:'different 02',id:55}}
what I expect to have an array like this :
[
{label:"dummy Altered01",id:2},
{label:"dummy02",id:5},
{label:'different',id:10},
{label:'different 02',id:55}
]
as you can see the object with the id of 2 is updated and other new objects are added to the array without erasing previous dummy02.
I don't know how should I compare id inside of two different arrays
I know this is not the best answer, so here's what I got
let listOfIds = newArray.map(item => item.id)
newArray = newArray.concat(arr.filter(item => !listOfIds.includes(item.id)))
First you map the newArray into a list of IDs.
Then newArray concatenates with the filtered original array (i.e. the array now doesn't have any items with ids in common with the latter )
Finally you update the state by setArr(newArr)
Hope this answers your question
Lets consider
a = [{label:"dummy01",id:2},{label:"dummy02",id:5}]
and new array is
b= [{label:'dummy Altered01',id:2},{label:'different',id:10},{label:'different 02',id:55}]
Now perform itearation over new array
b.forEach((item)=>{
let index = a.findIndex((x)=>x.id == item.id)
if(index > -1){
a[index].label = item.label
}
else
a.push(item)
})
console.log(a)

How to sort the nested object data in react-native

{
"lion":{
"age_in_years":"10",
"name":"king",
"country":"africa"
},
"elephant":{
"age_in_years":"15",
"name":"hero",
"country":"usa"
},
"racoon":{
"age_in_years":"5",
"name":"thanos",
"country":"syria"
},
}
This is the data I'm getting through a web socket in react-native. I want to sort it in ascending order based on the "age_in_years". So the oldest animal's data should be shown at top and the youngest data at the last.
You sould better work with an array insted of object as below, first map it into array and parse the age_in_years and sort it.
const obj2Array = Object.entries(<YourObject>).map(([key, value]) => ({...value, _id: key, age_in_years: parseInt(value.age_in_years)}));
const sorted = obj2Array.sort((a, b) => a.age_in_years - b.age_in_years);
Then you can use .reduce if you want the object back, nevertheless you can use the sorted array to render it.
Sort by age in years oldest first
// use slice() to copy the array
var byAge = array.slice(0);
byAge.sort(function(a,b) {
return a.age_in_years - b.age_in_years ;
});
Store the values in array and make a sort function.
const numbers = [info.lion.age_in_years, info.elephant.age_in_years, info.racoon.age_in_years];
const ascNumbers = numbers.sort((a,b) => a-b);
If you need descending make it like this:
const descNumbers = numbers.sort((a,b) => b-a);

Check if an array of arrays contains a value in javascript

I know that if there is an array of values it must be used this approach:
console.log(['joe', 'jane', 'mary'].includes('jane')); // true
But in case of an array of arrays, is there a short way to do it? Without other computations between.
For this input:
[['jane'],['joe'],['mary']]
You can use flat method to flatten the array. For more neted array, you can also mention depth like flat(depth)
let arr = [["jane"],["joe"],["mary"]];
arr.flat().includes('jane'); //true
You can easily achieve this result using some
arr.some((a) => a.includes("jane"))
const arr = [
["jane"],
["joe"],
["mary"]
];
const arr2 = [
["joe"],
["mary"]
];
console.log(arr.some((a) => a.includes("jane")));
console.log(arr2.some((a) => a.includes("jane")));
it can also be done by first flattening the 2d arrays in 1 d aaray and then using includes to find whether the array contains the element or not
var arr = [['jane'],['joe'],['marry']]
var newarr=[].concat(...arr)
var v=newarr.includes('jane')
console.log(v)

Remove and update an array without mutation in Javascript

I have an array :
let originalArr = ['apple', 'plum', 'berry'];
How can I remove "plum" from this array without mutating the originalArr?
I can think of below approach :
let copyArr = [...originalArr];
originalArr = copyArr.filter(item => {
return item !== 'plum';
});
You're creating two additional arrays: one copyArr and one filtered array. There's no need for both, creating just the filtered array should work fine, eg:
setOriginalArr(
originalArr.filter(item => item !== 'plum')
);
as an example, if originalArr is in state.
Calling .filter on an array doesn't mutate the array it was called on - it returns a new, separate array, so it's safe to use in React without cloning the original array beforehand.
You can use slice() method to extract items from/to specific indexes (without mutation of original array)
let originalArr = ['apple', 'plum', 'berry'];
let sliced = originalArr.slice(1, 2)
console.log(originalArr, sliced)

how to add different array item values into single array element?

i have an array like [x/0/2 , x/0/3 , y/3/1 , x/1/1 , x/0/3 , x/1/2],
i need to convert the elements range like [x/0/2-3 , y/3/1 , x/1/1-2]
Please give some suggestion for this.
Use reduce to iterate over the array and create an object grouped by the element root, then use Object.entries to pull out the correct information from the object.
const arr = ['x/0/2', 'x/0/3', 'y/3/1', 'x/1/1', 'x/0/3', 'x/1/2'];
const out = arr.reduce((acc, c) => {
// `split` out the separate parts of the element
const [ root1, root2, index ] = c.split('/');
// We'll use the first two parts as the object key
const key = `${root1}/${root2}`;
// If the key doesn't already exist create an empty
// array as its values
acc[key] = acc[key] || [];
// To prevent duplicates only add an index if it
// isn't already in the array
if (!acc[key].includes(index)) acc[key].push(index);
// Return the accumulator for the next iteration
return acc;
}, {});
// Then iterate over the object entries with `map`
const result = Object.entries(out).map(([ key, values ]) => {
// Return the joined up value
return `${key}/${values.join('-')}`;
});
console.log(result);
If I understand your question, you could create an array within the array to hold the range of values. Checking if the position in the array is an actual array let’s you know there are values that span a range within.
Example:
var values = [x/01, [x/20, x/21, x/22], x/03]
You could also create an object that could accomplish something similar depending on your needs.

Categories