concatenate array to array with specific positions JavaScript - javascript

i have a array of array like below.
const array1 = [[8,1,2,3,1],[3,1,1,1],[4,2,1]];
what i need to do is append six empty values " " in-between last two values for each element.
Expected output:
[ [ 8, 1, 2, '', '', '', '', '', '', 3, 1 ],
[ 3, 1 '', '', '', '', '', '' , 1, 1,],
[ 4, '', '', '', '', '', '', 2, 1 ] ]
What i tried:
i know how to append this to end of each element like below. can I modify my code with adding positioning?
What is the most efficient way to do this?
const array1 = [[8,1,2,3,1],[3,1,1,1],[4,2,1]];
const appendArray = new Array(6).fill('');
const map1 = array1.map(x => x.concat(appendArray));
console.log(map1)

Array .splice could be one way
const array1 = [[8,1,2,3,1],[3,1,1,1],[4,2,1]];
const map1 = array1.map(x => {
const copy = [...x];
copy.splice(-2, 0, ...Array(6).fill(''))
return copy;
})
console.log(map1)
Although ... personally I hate splice ... this is better because it's a one liner :p
const array1 = [[8,1,2,3,1],[3,1,1,1],[4,2,1]];
const map1 = array1.map(x => [...x.slice(0, -2), ...Array(6).fill(''), ...x.slice(-2)])
console.log(map1)

What concat does is just adds the empty value array to the end of array x. What you need is to separate the beginnings and the ends. Than return the array with spreded values like so
const array1 = [[8,1,2,3,1],[3,1,1,1],[4,2,1]];
const appendArray = new Array(6).fill('');
const map1 = array1.map(x => {
const beginning = x.slice(0, x.length - 2);
const end = x.slice(-2);
return [...beginning, ...appendArray, ...end]
});
console.log(map1)

Related

Form into a single array after iterating an object

How to get values of views into single array and get the two largest values in that array. The below is not creating single array. Could someone please advise ?
const data = [
{
id: 1,
views: 5678,
textData: "Sun"
},
{
id: 2,
views: 2500,
textData: "Moon"
},
{
id: 3,
views: 3500,
textData: "Earth"
},
{
id: 4,
views: 1250,
textData: "Sky"
}
]
data.map(({id, views, textData}) =>{
let myArr = [];
myArr.push(views);
let result = Math.max(...myArr);
console.log(result);
})
Desired Array: [5678, 2500, 3500, 1250 ]
Final Output : [5678,3500 ]
You can use Array#map to create an array of the views properties, then sort it.
const data=[{id:1,views:5678,textData:"Sun"},{id:2,views:2500,textData:"Moon"},{id:3,views:3500,textData:"Earth"},{id:4,views:1250,textData:"Sky"}];
let res = data.map(x => x.views).sort((a,b) => b - a).slice(0, 2);
console.log(res);
Get result in one loop without sorting, but the code doesn't look very clean.
const data=[{id:1,views:5678,textData:"Sun"},{id:2,views:2500,textData:"Moon"},{id:3,views:3500,textData:"Earth"},{id:4,views:1250,textData:"Sky"}];
const values1 = []
const values2 = [0, 0]
data.forEach(d => {
values1.push(d.views)
values2[0] = Math.max(values2[0], Math.min(d.views, values2[1]))
values2[1] = Math.max(d.views, values2[1])
})
console.log('single values: ', values1)
console.log('two largest values: ', values2)

How to keep null values when using `Array.join()`?

Consider the following,
const arr = [ 1, 5, null, null, 10 ];
console.log(arr.join(',')); // '1,5,,,10'
console.log(`${arr}`); // '1,5,,,10'
I need to keep these null values, how can I do this?
Only thing I could think of is something with reduce,
const result = arr.reduce((acc, el, index, self) => `${acc += el}${index !== self.length - 1 ? ',' : ''}`, '');
Any better way?
Using reduce()
const arr = [ 1, 5, null, null, 10 ];
const jin = arr.reduce((p, c) => `${p},${c}`);
console.log(jin);
Using map() and String()
Or use map() with String function to convert each value to a string so that join() will keep it:
const arr = [ 1, 5, null, null, 10 ];
const jin = arr.map(String).join(',');
console.log(jin);
Output
1,5,null,null,10
Not a pretty answer, but you could turn the nulls to strings.
const arr = [ 1, 5, null, null, 10 ];
const arr2 = arr.map(x => String(x));
console.log(arr2);
console.log(arr2.join(','));
const arr = [ 1, 5, null, null, 10 ]
console.log(String(arr.map(String)))
You could map everything to strings first by concatenating with an empty string:
const arr = [ 1, 5, null, null, 10 ];
console.log(arr.map((item) => item + "").join(',')); // '1,5,null,null,10'
console.log(`${arr}`); // '1,5,,,10'

JavaScript how to find unique values in an array based on values in a nested array

I have a nested/multi-dimensional array like so:
[ [ 1, 1, a ], [ 1, 1 , b ], [ 2, 2, c ], [ 1 ,1, d ] ]
And I want to filter it so that it returns only unique values of the outer array based on the 1st value of each nested array.
So from the above array, it would return:
[ [1,1,a] [2,2,c] ]
Am trying to do this in vanilla javascript if possible. Thanks for any input! =)
Here is my solution.
const dedup = arr.filter((item, idx) => arr.findIndex(x => x[0] == item[0]) == idx)
It looks simple and also somehow tricky a bit.
I realize there's already three solutions, but I don't like them. My solution is
Generic - you can use unique with any selector function
O(n) - it uses a set, it doesn't run in O(n^2) time
So here it is:
/**
* #param arr - The array to get the unique values of
* #param uniqueBy - Takes the value and selects a criterion by which unique values should be taken
*
* #returns A new array containing the original values
*
* #example unique(["hello", "hElLo", "friend"], s => s.toLowerCase()) // ["hello", "friend"]
*/
function unique(arr, uniqueBy) {
const temp = new Set()
return arr.filter(v => {
const computed = uniqueBy(v)
const isContained = temp.has(computed)
temp.add(computed)
return !isContained
})
}
const arr = [ [ 1, 1, 'a' ], [ 1, 1, 'b' ], [ 2, 2, 'c' ], [ 1, 1, 'd' ] ]
console.log(unique(arr, v => v[0]))
You could filter with a set and given index.
const
uniqueByIndex = (i, s = new Set) => array => !s.has(array[i]) && s.add(array[i]),
data = [[1, 1, 'a'], [1, 1, 'b'], [2, 2, 'c'], [1, 1, 'd']],
result = data.filter(uniqueByIndex(0));
console.log(result);
const input = [[1,1,'a'], [1,1,'b'], [2,2,'c'], [1,1,'d']]
const res = input.reduce((acc, e) => acc.find(x => x[0] === e[0])
? acc
: [...acc, e], [])
console.log(res)
Create the object with keys as first element of array. Iterate over array, check if the first element of array exist in the Object, if not push into the array.
const nestedArr = [ [1,1,"a"], [1,1,"b"], [2,2,"c"], [1,1,"d"] ];
const output = {};
for(let arr of nestedArr) {
if(!output[arr[0]]) {
output[arr[0]] = arr;
}
}
console.log(Object.values(output));
Another solution, would be to maintain the count of first array element and if the count is equal to 1, then push in the final array.
const input = [ [1,1,"a"], [1,1,"b"], [2,2,"c"], [1,1,"d"] ],
count = {},
output = [];
input.forEach(arr => {
count[arr[0]] = (count[arr[0]] || 0) + 1;
if(count[arr[0]] === 1) {
output.push(arr);
}
})
console.log(output);

How can I check if the array of objects have duplicate property values with more properties?

I have searched StackOverflow and found this answer, but it does not solve my problem.
My problem is, my array is like this:
let arr = [
{type: 1, id: 1, name:'aa'},
{type: 1, id: 1, name:'bb'},
{type: 2, id: 1, name:'cc'}
]
And I need to find same type and same id and then recognize that this is duplicate object. Above, arr[0] and arr[1] is a duplicate but arr[0] and arr[2] are not. I have tried using ES6 methods such as .some(), .every(), and a Set(), but non of these have worked for me. How can I solve this problem?
You can use .map() to map each object to a string. Each string takes the shape of type-id for that object. Then, using a Set you can remove all duplicate strings. You can then check if the set size equals the array length to determine if there are any duplicates or not in the array:
const containsDups = arr => new Set(arr.map(({type, id}) => `${type}-${id}`)).size !== arr.length;
const arr = [{type: 1, id: 1, name:'aa'},{type: 1, id: 1, name:'bb'},{type: 2, id: 1, name:'cc'}];
console.log(containsDups(arr));
It is possible to group by properties such as type and id and then check whether names more than 1. If yes, it means, that there is at least one duplicate:
const result = [...arr.reduce((r, o) => {
const key = o.type + '-' + o.id;
const item = r.get(key) || Object.assign({}, o, {
names: []
});
item.names.push(o.name);
return r.set(key, item);
}, new Map).values()];
An example:
let arr = [{type: 1, id: 1, name:'aa'},{type: 1, id: 1, name:'bb'},{type: 2, id: 1, name:'cc'}]
const result = [...arr.reduce((r, o) => {
const key = o.type + '-' + o.id;
const item = r.get(key) || Object.assign({}, o, {
names: []
});
item.names.push(o.name);
return r.set(key, item);
}, new Map).values()];
console.log(`Is there duplicates: `, result.some(s => s.names.length > 1));
you can use Set:
Set is a new data object introduced in ES6. Because Set only lets you store unique values
const seen = new Set();
const arr = [
{type: 1, id: 1, name:'aa'},
{type: 1, id: 1, name:'bb'},
{type: 2, id: 1, name:'cc'}
];
const filteredArr = arr.filter((el, index) => {
const duplicate = seen.has(el.type, el.id);
seen.add(el.type, el.id);
console.log('index: '+ index +' is duplicate: '+ duplicate);
return !duplicate; // if you just need a boolean, this is what you are looking for.
});
console.log('new array: ' + JSON.stringify(filteredArr));

How to get number occurrences of any element of an array in another array in Javascript?

I have an array:
const myArray1 = [{tags: ['tag-1', 'tag-2']}, {tags: ['tag-1']}, {tags: ['tag-5', 'tag-8']}]
And an array2:
const myArray2 = [
{
tags: [
"tag-122",
"tag-1",
"tag-2",
"tag-12"
]
},
{
tags: [
"tag-1",
"tag-10",
"tag-12"
]
},
{
tags: [
"tag-5"
]
}
];
I want to get an array
const resultArray = [{tags: ['tag-1', 'tag-2'], count: 2}, {tags: ['tag-1'], count: 2}, {tags: ['tag-5', 'tag-8'], count: 1}]
For every element in myArray1 check if any element of array tags in myArray1 contains in myArray2. if contains, find the count of occurrences
I try to make an array of myArray2 tags and then find occurrences in array for every element of myArray1
const result = myArray2.reduce((acc, el) => {
el.tags && el.tags.map(tag => acc.push(tag));
return acc;
}, []);
I'd transform the myArray2 into an array of Sets for reduced computational complexity, then .map the array2 and check if .some of the tags being iterated over exists in the set, counting the number of occurrences with reduce:
const myArray1=[{tags:["tag-1","tag-2"]},{tags:["tag-1"]},{tags:["tag-5","tag-8"]}],
myArray2=[{tags:["tag-122","tag-1","tag-2","tag-12"]},{tags:["tag-1","tag-10","tag-12"]},{tags:["tag-5"]}];
const arr2Sets = myArray2.map(({ tags }) => new Set(tags));
const resultArray = myArray1.map(({ tags }) => {
const count = arr2Sets.reduce(
(a, set) => a + tags.some(tag => set.has(tag)),
0
);
return { tags, count };
});
console.log(resultArray);

Categories