javascript: get subarray from an array by indexes - javascript

Is there a one-line code to get an subarray from an array by index?
For example, suppose I want to get ["a","c","e"] from ["a","b","c","d","e"] by [0,2,4]. How to do this with a one-line code? Something like ["a","b","c","d","e"][0,2,4]..

You could use map;
var array1 = ["a","b","c"];
var array2 = [0,2];
var array3 = array2.map(i => array1[i]);
console.log(array3);

You can use filter
const arr = ['a', 'b', 'c'];
const indexes = [0, 2];
const result = arr.filter((elt, i) => indexes.indexOf(i) > -1);
document.body.innerHTML = result;

You can use a combination of Array#filter and Array#includes
const array = ['a','b','c'];
console.log(array.filter((x,i) => [0,2].includes(i)));

You can use Array.prototype.reduce()
const arr = ['a', 'b', 'c', 'd', 'e'];
const indexes = [0, 2, 4];
const result = indexes.reduce((a, b)=> {
a.push(arr[b]);
return a;
}, []);
console.log(result);

Related

How to replace array element with respect to Index on another array

I have one array which contains values array1 = [a,b,c,d,e,f,g] and another array contains index of array1 and the value to be replaced array2 = [[2,u],[3,x],[6,z]].
Now I want to replace value of array1 with respect to array2 please not array2 consist of [array1_position, value_to_be_replaced]
Now my new arra1 should look like this array1 = [a,b,u,x,e,f,z].
I can do this with for loop but its again time consuming. what trick can i use to replace the value quickly. I am just learning about arrays and have a little knowledge on it.
I don't think there is any shorthand for such a verbose question.
Something on top of my mind is
array2.forEach((el) => {
array1[el[0]] = el[1];
})
you could do this
array2.forEach(arr => {
const [index, replaced] = arr;
array1[index] = replaced;
});
You can take fromEntries of the other array then just map it:
var array1 = ['a','b','c','d','e','f','g'];
var array2 = [[2,'u'],[3,'x'],[6,'z']];
var d=Object.fromEntries(array2);
var result = array1.map((val, i)=> d[i] || val);
console.log(result);
With an ordered array2 by indices, you could take a closure over an index of this array and map the values from eithe the first array or the replacements array.
var array1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
array2 = [[2, 'u'], [3, 'x'], [6, 'z']],
result = array1.map(
(j => (v, i) => i === array2[j][0] ? array2[j++][1] : v)
(0)
);
console.log(result);

JavaScript split and merge arrays by conditions

I have an array like [a, b, c, d] and I want to split it into 2 arrays like [a, b] and [c, d] and then merge it to have final result like [[a, b],[c, d]]. Is it possible to do without for loop?
You can use slice and push method like this
var arr = ['a', 'b', 'c', 'd'];
let index = 2;
let result = [];
result.push(arr.slice(0, index));
result.push(arr.slice(index))
console.log(result);
let arr = [0, 1, 9, 10, 8];
let arr2 = arr.slice(1,3);
let resultArr = [];
if(arr2[1] > 1){
resultArr.push(99);
}
else{
resultArr.push(100);
}
console.log(resultArr)
You might like something like this:
a = 8;
b = { some: 'say'};
c = 'life';
d = true;
let o = {
'a': [a, b, c, d],
'a1': [],
'a2': []
}
nSwitchBefore = 2;
o.a.forEach(function(item, i) {
i < nSwitchBefore ? this.a1.push(item) : this.a2.push(item) ;
}.bind(o));
console.log(o);
Within the function block there is room for extra handling your array items. Like filtering or special treatment of certain types, using all conditions you want.
yes without loop you can do this But you should know at what index you have to split the array.
var arr = ['a', 'b', 'c', 'd'];
var indexToSplit = arr.indexOf('c');
var first = arr.slice(0, indexToSplit);
var second = arr.slice(indexToSplit + 1);
var final = [first, second]
console.log(final);
I found another solution for this issue, without writing loops
Lodash Chunk does this logic
_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
https://lodash.com/docs/

count items in an one array, if the number of instances is the same as the length of a different array, return the item, javascript

I have two arrays, id like to return the items from array1 if they appear as much as the length of array2
I understand how to do this in python, but I cant figure out how to do it in javascript
arr1 = ['a', 'b', 'c', 'c']
arr2 = ['one', 'two']
arr3 = []
for i in arr1:
if arr1.count(i) == len(arr2):
arr3.append(i)
desired result would be ['c']
Can someone please help me write this in javascript?
You can use reduce and filter
Here idea is :-
First use elements of arr1 as key on obj, if key is already there increment it's value, else set it to zero,
Now take the key's of obj and filter if it's value is equal to length of arr2
let arr1 = ['a', 'b', 'c', 'c']
let arr2 = ['one', 'two']
let obj = arr1.reduce((op,inp)=>{
let key = inp.toLowerCase()
op[key] = op[key] || 0
op[key]++
return op
},{})
let final = Object.keys(obj).filter(key=>{
return obj[key] === arr2.length
})
console.log(final)
Note :- Here i ignored case, if you want both case to be different than you can remove this line
let key = inp.toLowerCase()
Nested loops could do that. One for the for, and one for the count:
var arr1 = ['a', 'b', 'c', 'c'];
var arr2 = ['one', 'two'];
var arr3 = [];
var unique = new Set(arr1);
var len2 = arr2.length;
for(var i of unique){
var count = 0;
for(var j of arr1)
if(j === i)
count++;
if(count == len2)
arr3.push(i);
}
console.log(arr3);
Side remark: I think that Python code would result in ['c','c'], though I have not actually tried.
First use reduce() to create object of whose keys will elements of arr1 and value will be their count. Then filter() its keys according to given condition.
let arr1 = ['a', 'b', 'c', 'c']
let arr2 = ['one', 'two']
const obj = arr1.reduce((ac,a) => (ac[a] = ac[a] + 1 || 1, ac),{});
let res = Object.keys(obj).filter(k => obj[k] === arr2.length);
console.log(res)

How to insert a new element at any position of a JS array?

I have an array [a, b, c]. I want to be able to insert a value between each elements of this array like that: [0, a, 0, b, 0, c, 0].
I guess it would be something like this, but I can't make it works.
for (let i = 0; i < array.length; i++) {
newArray = [
...array.splice(0, i),
0,
...array.splice(i, array.length),
];
}
Thank you for helping me!
For getting a new array, you could concat the part an add a zero element for each element.
var array = ['a', 'b', 'c'],
result = array.reduce((r, a) => r.concat(a, 0), [0]);
console.log(result);
Using the same array
var array = ['a', 'b', 'c'],
i = 0;
while (i <= array.length) {
array.splice(i, 0, 0);
i += 2;
}
console.log(array);
A bit shorter with iterating from the end.
var array = ['a', 'b', 'c'],
i = array.length;
do {
array.splice(i, 0, 0);
} while (i--)
console.log(array);
Another way if you want to exclude the start and end of array is :
var arr = ['a', 'b', 'c']
var newArr = [...arr].map((e, i) => i < arr.length - 1 ? [e, 0] : [e]).reduce((a, b) => a.concat(b))
console.log(newArr)
You can use map() with ES6 spread syntax and concat()
var arr = ['a', 'b', 'c']
var newArr = [0].concat(...arr.map(e => [e, 0]))
console.log(newArr)
Another ES6+ version using flatmap (if creation of a new array instead is ok):
['a', 'b', 'c', 'd']
.flatMap((e, index) => index ? [e, 0] : [0, e, 0])
Another way:
var a = ['a', 'b', 'c'],
b;
b = a.reduce((arr, b) => [...arr, b, 0], []);
console.log(b);
You could use .reduce():
function intersperse(arr, val) {
return arr.reduce((acc, next) => {
acc.push(next);
acc.push(val);
return acc;
}, [val]);
}
console.log(intersperse(['a', 'b', 'c'], 0));
Or to accomplish this by modifying the original array:
function intersperse(arr, val) {
for (let i = 0; i <= arr.length; i += 2) {
arr.splice(i, 0, val);
}
return arr;
}
console.log(intersperse(['a', 'b', 'c'], 0));
You can try with the below code. It will add 0 in middle of each two element of the array
console.log(['a', 'b', 'c'].reduce((r, a) => r.concat(a,0), [0]).slice(1, -1))
You just need to loop over the array elements and add the new element in each iteration, and if you reach the last iteration add the new element after the last item.
This is how should be your code:
var arr = ['a', 'b', 'c'];
var results = [];
arr.forEach(function(el, index) {
results.push(addition);
results.push(el);
if (index === arr.length - 1)
results.push(addition);
});
Demo:
This is a Demo snippet:
var arr = ['a', 'b', 'c'];
var results = [];
var addition = 0;
arr.forEach(function(el, index) {
results.push(addition);
results.push(el);
if(index === arr.length -1)
results.push(addition);
});
console.log(results);
If you want to insert elements only after existing ones:
console.log(["a", "b", "c"].map(i => [i, 0]).flat())
You could do
let arr = ['a', 'b', 'c'];
arr = arr.reduce((a, b) => {
a.push(0);
a.push(b);
return a;
}, []);
arr.push(0);
console.log(arr);
function insert(arr, elm) {
var newArr = [];
for(var i = 0; i < arr.length; i++) { // for each element in the array arr
newArr.push(elm); // add the new element to newArr
newArr.push(arr[i]); // add the current element from arr
}
newArr.push(elm); // finally add the new element to the end of newArr
return newArr;
}
console.log(insert(["a", "b", "c"], 0));
It could be done with strings by splitting and joining.
var arr = ['a', 'b', 'c'];
var newArray = ("0," + arr.toString().split(",").join(",0,")).split(",");
console.log(newArray);
This looks like the intersperse algorithm but does some addition to the head and tail as well. So i call it extrasperse.
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
extrasperse = (x,a) => a.reduce((p,c,i) => (p[2*i+1] = c, p), Array(2*a.length+1).fill(x));
console.log(JSON.stringify(extrasperse("X",arr)));
let arr = ['a', 'b', 'c'];
function insert(items, separator) {
const result = items.reduce(
(res, el) => [...res, el, separator], [separator]);
return result;
}
console.log(insert(arr, '0'));
all of the above methods in very long strings made my android computer run on React Native go out of memory.
I got it to work with this
let arr = ['a', 'b', 'c'];
let tmpArr = [];
for (const item in arr) {
tmpArr.push(item);
tmpArr.push(0);
}
console.log(tmpArr);
Another way is to use some functional methods like zip and flat. Check out lodash.
const array = ['a', 'b', 'c']
const zeros = Array(array.length + 1).fill(0)
const result = _.zip(zeros, array).flat().filter(x => x !== undefined)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
Straight forward way of inserting only between:
const arr = ['a', 'b', 'c'];
arr.map((v, i) => !i || i === arr.length - 1 ? [v] : [0, v]).flat()
I think this is correct, ie, just adds the element between the elements of the array, and should be pretty efficient:
const intersperse = ([first, ...tail]: any[], element: any) => (
(first === undefined) ? [] : [first].concat(...tail.map((e) => [element, e]))
);
console.log(intersperse([], 0));
console.log(intersperse([1], 0));
console.log(intersperse([1, 2, 3], 0));
Thanks for your question and thanks to all contributors, for their answers.
This would be my approach
const arr = ["a", "b", "c"];
let toAdd = 0;
for (let i = 0; i <= arr.length; i += 2) {
arr.splice(i, 0, toAdd);
}
console.log(arr);
or
const arr = ["a", "b", "c"];
let toAdd = 0;
const newArr = [];
newArr.unshift(toAdd);
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
newArr.push(toAdd);
}
console.log(newArr);
Cheers
Nav

JavaScript Array mapping

Consider the following scenario;
var defaultArr = ['a', 'b', 'c', 'd'];
var availArr = [];
var selectedArr = [];
If I am passing array some index's value in param's, I need to split up my array's
Example:
If Array Index : 0,2
Expected result:
availArr = ['b', 'd'];
selectedArr = ['a', 'c'];
Is there any default method to achieve this?
Failrly easy with Array.reduce
var defaultArr = ['a', 'b', 'c', 'd'];
var indexes = [0,2];
var result = defaultArr.reduce(function(p, c, i){
if(indexes.indexOf(i)>-1)
p.selectedArr.push(c);
else
p.availArr.push(c);
return p;
}, {availArr: [], selectedArr:[]});;
console.log('availArr',result.availArr);
console.log('selectedArr',result.selectedArr);
This works because reduce takes a callback argument which is passed 3 arguments - in my example above
p the seed object passed in
c the current array element
i the index of the current element
And uses that information along with indexOf to determine which result array to push to.
You could use Array#reduceRight and iterate the indices array.
var defaultArr = ['a', 'b', 'c', 'd'],
availArr = defaultArr.slice(),
selectedArr = [],
indices = [0, 2];
indices.reduceRight(function (_, a) {
selectedArr.unshift(availArr.splice(a, 1)[0]);
}, 0);
console.log(availArr);
console.log(selectedArr);
var defaultArr = ['a', 'b', 'c', 'd'];
var availArr = [];
var selectedArr = [];
function splitArray(indexes) {
availArr = defaultArr;
indexes.forEach(function(idx) {
let item = availArr.splice(idx, 1)[0];
selectedArr.push(item);
})
}
splitArray([0, 2]);
console.log(availArr);
console.log(selectedArr);
You can use Array methods like forEach and includes
var given = ['a', 'b', 'c', 'd'];
var indexes = [0, 2];
var available = [];
var selected = [];
given.forEach(function (v, i) {
if (indexes.includes(i)) {
selected.push(v);
} else {
available.push(v);
}
});
document.write(JSON.stringify({
given: given,
available: available,
selected: selected
}));
In JS Array.prototype.reduceRight() is the ideal functor to iterate over an array and to morph it by removing items. Accordingly i would approach this job as follows;
var defaultArr = ['a', 'b', 'c', 'd'],
indices = [0, 2];
result = defaultArr.reduceRight((p,c,i,a) => indices.includes(i) ? p.concat(a.splice(i,1)) : p ,[]);
console.log(defaultArr,result);
You can use array.splice + array.concat to achieve this
var defaultArr = ['a', 'b', 'c', 'd'];
var availArr = [];
var selectedArr = [];
function parseIndexes(indexArr){
var deleteCount = 0;
availArr = defaultArr.map(x=>x);
indexArr.forEach(function(i){
selectedArr = selectedArr.concat(availArr.splice(i-deleteCount,1))
deleteCount++;
});
console.log(availArr, selectedArr)
}
parseIndexes([0,2])
With only Array.filter
var array = ['a', 'b', 'c', 'd'];
var indexes = [0, 2]
array.filter(function(el, i) {
return indexes.indexOf(i) !== -1
});
// ["a", "c"]
With array the array of your elements, objects, strings... and indexes the array containing all the indexes of the elements you want to keep, you just remove from the arrayarray all the elements whose id isn't in theindexes array.
The array of all selected entries can be obtained in one line via the Array.map:
var defaultArr = ['a', 'b', 'c', 'd']
var index = [0,2]
var selectedArr = index.map(i => defaultArr[i]) //=> ['a', 'c']
Then the array of the remaining entries can be retrieved e.g. with the Ramda's difference operator:
var availArr = R.difference(defaultArr, selectedArr) //=> ['b', 'd']

Categories

Resources