How to append two element in array? - javascript

I am pushing element in the array using javascript .
and i am getting output like this
["api", "management", "provision", "tenant", "external", "provider"] => Correct
after pushing the data into array now i want append two element from the array management and provision and want output like this
["api", "management/provision", "tenant", "external", "provider"]
how would i do this ?
any example would be good for me
thanx in advance

The simplest thing you can do is to remove them both, join with / and put at the right place. You can do this in a few lines of code:
const input = ["api", "management", "provision", "tenant", "external", "provider"];
input.splice(1, 3, input.slice(1, 3).join('/'));
// now input contains ["api", "management/provision", "external", "provider"]
This can be further made more readable and reusable:
function mergeTerms(startIndex, endIndex, array) {
const input = array.slice(0); // make a shallow copy of the array in order not to mutate it
input.splice(startIndex, endIndex, input.slice(startIndex, endIndex).join('/'));
return input;
}
and then:
mergeTerms(1, 3, input);

Lets say its the var array that holds the values.
var temp = array.splice(2,3);
array[1] = array[1]+"/"+temp;

function mergeArrayEntries(e1, e2, arr) {
var index = -1;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == e1) {
index = i;
}
if (arr[i] == e2 && index > -1) {
arr[index] = arr[index]+"/"+arr[i];
arr.splice(i, 1);
}
}
}
this function searches for e1 and e2 in the arr and once found, it merges them to position of e1 and deletes e2 entry in arr.
hope it helps

Not the nicest code, and not at all reusable, but will give you what you are looking for --- just another approach
var array = ["api", "management", "provision", "tenant", "external", "provider"];
var subArray = [];
subArray.push(array[1]);
subArray.push(array[2])
array.splice(1, 2);
subArray = subArray.join("/")
array.splice(1, 0, subArray);

Related

Map an array to set empty elements

Given:
let input = [0, 1, 2,,,,,7]
I want to get:
let output = [, 1, 22, 333, 4444, 55555, 666666, 7777777]
(i.e. value equal key times the key)
How can I map (or equivalent) input including empty values? If I do input.map() I will get [, 1, 22,,,,,7777777] because map will -of course- not iterate empty values. Data can be arbitrary, strings, objects, numbers, etc. Using numbers in this example for simplicity.
You can fill the array before applying a mapping function so that all indexes are iterated over, including empty ones.
let result = input.fill().map((_,index)=>{/*...*/});
The mapping function provided as the second argument to Array.from can be similarly used.
let result = Array.from({length: input.length}, (_, index)=>{/*...*/});
Spread syntax does not ignore empty slots, so we can create a copy of the array with spread syntax and map over that. This has an added advantage of having the elements at each index available as well.
let result = [...input].map((elem, idx)=>{/*...*/});
map() can't include empty values. w3schools
map() does not execute the function for array elements without values.
So, either iterate the array with a for-loop:
out = [];
for (var i = 0; i < input.length; i++) {
var item = input[i];
if (item != null)
out[i] = item.toString().repeat(item);
}
Or create another mapx() functor:
Array.prototype.mapx = function(fn) {
var out = [];
for (var i = 0; i < this.length; i++) {
var item = this[i];
// if (item == null) item = sherlockHolmesKnow();
out[i] = fn(item, i);
}
return out;
};
and apply on the input:
input.mapx( (val, index) => (val == null ? null : (val+'').repeat(val)) )
which yields ["", "1", "22", null, null, null, null, "7777777"].
Let's skip the AI part of clever guessing the numbers in the empty slots.
Here is another approach too verbose but it works, with for loop you can loop through null values
arr=[0, 1, 2,,,,,7]
res=[]
f=false
for(let i=0;i<arr.length-1;i++){
if(arr[i]!=undefined){
res.push(Number(String(arr[i]).repeat(arr[i])))
//f=false
}
if(arr[i]==undefined&&f==false){
n= arr[i-1]
f=true
res.push(Number(String(n+1).repeat(n+1)))}
if(f==true && arr[i]==undefined){
n=Number(res[res.length-1].toString().charAt(0))+1
res.push(Number(String(n).repeat(n)))
}
}
console.log(res)

Finding an array of arrays... inside another array

I'm dealing with 'arrays of arrays' and trying to test if all 'sets' contained in the second array are present in the first array.
var arr = [['Netherlands','PP3a'],['Austria','PP16a'],['Estonia','PP3a'],['Luxembourg','PP3a'],['Belgium','PP3a']];
var n = [['Luxembourg','PP3a'],['Netherlands','PP3a'],['Belgium','PP3a']];
In my example https://jsfiddle.net/mnb8jddw/ they clearly are present, but the code (which incidentally seems to work with numbers), reads false. I've obviously got myself confused and would really appreciate some help as I suspect I'm taking the wrong approach.
var arr = [
['Netherlands', 'PP3a'],
['Austria', 'PP16a'],
['Estonia', 'PP3a'],
['Luxembourg', 'PP3a'],
['Belgium', 'PP3a']
];
var n = [
['Luxembourg', 'PP3a'],
['Netherlands', 'PP3a'],
['Belgium', 'PP3a']
];
function searchForArray(haystack, needle) {
var i, j, current;
for (var i in haystack) {
if (needle.length === haystack[i].length) {
current = haystack[i];
for (j = 0; j < needle.length && needle[j] === current[j]; ++j);
if (j === needle.length)
return i;
}
}
return -1;
}
console.log(searchForArray(arr, n)); // -1 = false
I'm not sure that it is the answer you are looking for, but if you are looking for a quick and dirty solution, you could try something like this:
const lookup = (ar, sets) => {
// concatenate each entry in the searched array
const _hashed = ar.map(i => i.join(''))
return sets.every((set) => {
// contatenate each entry to look for
const _set = set.join('')
// does the searched array contain the concatenated string?
return _hashed.indexOf(_set) > -1
})
}
console.log(lookup(arr, n)) // => true
Note that the order of the elements matters (ie: ['Luxembourg', 'PP3a'] will match, but ['PP3a', 'Luxembourg'] won't)
See updated fiddle

Turning an array into a multidimensional array? Javascript

I am struggling to create a simple function that will taking an array such as
["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"]
and turn it into a multidimensional array that looks like this
[["chicken","10 lbs"],["hot sauce","4 cups"],["celery","1 stalk"]]
essentially index 0 and 1 merge into a new sub array then 2 and 3 merge and so on...
i am trying for loops where i increases +2 but i can't get it quite right, i thought this would be a simple solution but the loops i've made so far are almost crashing my browser...any help would be appreciated. thanks
EDIT: WOW Thanks for all the rapid responses! I looked at everything and learned a lot!
Using Array#reduce(), Array#concat() & Array#slice()
var data = ["chicken", "10 lbs", "hot sauce", "4 cups", "celery", "1 stalk"];
var res = data.reduce((a, c, i) => {
return i % 2 === 0 ? a.concat([data.slice(i, i + 2)]) : a;
}, []);
console.log(res)
Hope this helps...
I added some comments but feel free to ask if you need more explanation.
There are definitely more advanced (and much shorter!) ways of doing this, but this is the most intuitive and easiest to understand, in my opinion.
Right now, if there is an odd amount of elements, the last element will end up being "undefined." Let me know if you'd like this to work differently.
var array = ["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"];
function combineTwo(inputArray) {
//Starting with the beginning of the array, this function combines index 0 with 1, 2 with 3, and so on for the entire length of the array
var result = []; //this will the variable that we store our result in
for (var i = 0; i < inputArray.length; i+=2) {
//This for loop iterates through every other index of the array... for example: 0, 2, 4, etc.
result.push([inputArray[i], inputArray[i+1]]); //Adds i and i+1 as a new array to the result array
}
return result;
}
console.log(combineTwo(array));
There are many ways to do this. Here, we are using the Array.map() method to return items into a new array and then cleaning out any undefined elements using Array.filter().
var startArray = ["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"];
// Create a new array by iterating the first one...
var resultArray = startArray.map(function(item, index, arry){
// If we are on an even index...
if(index % 2 === 0){
// Send the item and the one that follows it into the new array
return [item, arry[index + 1]];
}
});
// The resulting array will contain undefined for each enumeration that didn't
// return anything, so we can clean that up by filtering out the undefined elements
resultArray = resultArray.filter(function( element ) {
return element !== undefined;
});
console.log(resultArray);
However, it seems that you want to make an array of ingredients and ingredients combine to make a final product, so creating an object would be more appropriate, since objects are really nothing more than groupings of key/value pairs and can be more versatile if you plan on doing OOP operations. The result here is an array of recipe objects:
// Create a new array that will store recipe objects
var cookbook = [];
function addRecipeToCookbook(ary){
// Create a "recipe" object
var recipe = {};
// Iterate the passed array...
ary.forEach(function(item, index, array){
// If we are on an even index...
if(index % 2 === 0){
// Add the item as a new property of the recipe object with the quantity as the value
recipe[item] = array[index + 1];
}
});
// Add the object to the new array
cookbook.push(recipe);
}
// Now you can add as many recipies as you like:
var recipeArray1 = ["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"];
var recipeArray2 = ["pork","2 lbs","BBQ sauce","2 cups","onion","3 ounces"];
var recipeArray3 = ["beef","5 lbs","worchestishire sauce","4 ounces","garlic","1 clove"];
// Just call the reusable function and pass a recipe array:
addRecipeToCookbook(recipeArray1);
addRecipeToCookbook(recipeArray2);
addRecipeToCookbook(recipeArray3);
console.log(cookbook);
Another option is to take in a second argument that dictates how many items you would like in each subarray. For instance:
function squash(arr, num) {
let results = [];
let start, end;
for (let i = 1; i < arr.length; i++) {
start = (i - 1) * num;
end = i * num;
let sliced = arr.slice(start, end);
if (start >= arr.length) { // need to make sure we don't go passed the end
break;
}
results.push(sliced);
}
return results;
}
Just another way to do this using .reduce():
var array = ["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"];
var array2d = array.reduce((array, element, index) => {
if (index % 2 > 0) {
array.push(array.pop().concat([element]));
} else {
array.push([element]);
}
return array;
}, []);
console.log(array2d);
A more generic method that could be used might look like the following:
function group(amount) {
return (array) => array
.reduce((array, element, index) => {
if (index % amount > 0) {
array.push(array.pop().concat([element]));
} else {
array.push([element]);
}
return array;
}, []);
}
var a = ["chicken","10 lbs","hot sauce","4 cups","celery","1 stalk"];
var b = ["chicken","10","lbs","hot sauce","4","cups","celery","1","stalk"];
var group2 = group(2);
var group3 = group(3);
var a2d = group2(a);
var b2d = group3(b);
console.log(a2d);
console.log(b2d);
most intuitive for me, just keep yanking items off the original array until it is empty:
let array = ["chicken", "10 lbs", "hot sauce", "4 cups", "celery", "1 stalk"],
newArray = [];
while (array.length) {
newArray.push([array.shift(), array.shift()]);
}
console.log(newArray);

Get the array index of duplicates

In a JavaScript array how can I get the index of duplicate strings?
Example:
MyArray = ["abc","def","abc"]; //----> return 0,2("abc");
Another example:
My Array = ["abc","def","abc","xyz","def","abc"]
//----> return 0,2,5("abc") and 1,4("def");
I have no idea how to do this.
Thanks in advance for your help!
Update 01/2022: It's not 2013 anymore, and many things have changed. I neither recommend modifying the prototype, nor is the approach in this answer the "best" as it requires several iterations over the array.
Here's an updated version of the original answer, retaining its spirit, as well as the original answer below.
function getDuplicates<T>(input: T[]): Map<T, number[]> {
return input.reduce((output, element, idx) => {
const recordedDuplicates = output.get(element);
if (recordedDuplicates) {
output.set(element, [...recordedDuplicates, idx]);
} else if (input.lastIndexOf(element) !== idx) {
output.set(element, [idx]);
}
return output;
}, new Map<T, number[]>());
}
Yet another approach:
Array.prototype.getDuplicates = function () {
var duplicates = {};
for (var i = 0; i < this.length; i++) {
if(duplicates.hasOwnProperty(this[i])) {
duplicates[this[i]].push(i);
} else if (this.lastIndexOf(this[i]) !== i) {
duplicates[this[i]] = [i];
}
}
return duplicates;
};
It returns an object where the keys are the duplicate entries and the values are an array with their indices, i.e.
["abc","def","abc"].getDuplicates() -> { "abc": [0, 2] }
Another less sophisticated approach:
Iterate over the whole array and keep track of the index of each element. For this we need a string -> positions map. An object is the usual data type to use for this. The keys are the elements of the array and the values are arrays of indexes/positions of each element in the array.
var map = {};
for (var i = 0; i < arr.length; i++) {
var element = arr[i]; // arr[i] is the element in the array at position i
// if we haven't seen the element yet,
// we have to create a new entry in the map
if (!map[element]) {
map[element] = [i];
}
else {
// otherwise append to the existing array
map[element].push(i);
}
// the whole if - else statement can be shortend to
// (map[element] || (map[element] = [])).push(i)
}
Now you can iterate over the map and remove all entries where the array value has a length of one. Those are elements that appear only once in an array:
for (var element in map) {
if (map[element].length === 1) {
delete map[element];
}
}
Now map contains a string -> positions mapping of all duplicate elements of the array. For example, if you array is ["abc","def","abc","xyz","def","abc"], then map is an object of the form
var map = {
'abc': [0,2,5],
'def': [1,4]
};
and you can process it further in any way you like.
Further reading:
Eloquent JavaScript - Data structures: Objects and Arrays
MDN - Working with objects
MDN - Predefined core objects, Array object
This covers finding the indices efficiently:
var inputArray = [1, 2, 3, 4, 5, 6, 6, 7, 8, 9];
var encounteredIndices = {};
for(var i = 0; i < inputArray.length; i++)
if (encounteredIndices[inputArray[i]])
console.log(i); // Or add to some array if you wish
else
encounteredIndices[inputArray[i]] = 1;

Delete zero values from Array with JavaScript

I have an array with name "ids" and some values like ['0','567','956','0','34']. Now I need to remove "0" values from this array.
ids.remove ("0"); is not working.
Here's a function that will remove elements of an array with a particular value that won't fail when two consecutive elements have the same value:
function removeElementsWithValue(arr, val) {
var i = arr.length;
while (i--) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
return arr;
}
var a = [1, 0, 0, 1];
removeElementsWithValue(a, 0);
console.log(a); // [1, 1]
In most browsers (except IE <= 8), you can use the filter() method of Array objects, although be aware that this does return you a new array:
a = a.filter(function(val) {
return val !== 0;
});
Use splice method in javascript. Try this function:
function removeElement(arrayName,arrayElement)
{
for(var i=0; i<arrayName.length;i++ )
{
if(arrayName[i]==arrayElement)
arrayName.splice(i,1);
}
}
Parameters are:
arrayName:- Name of the array.
arrayElement:- Element you want to remove from array
Here's one way to do it:
const array = ['0', '567', '956', '0', '34'];
const filtered = array.filter(Number);
console.log(filtered);
For non-trivial size arrays, it's still vastly quicker to build a new array than splice or filter.
var new_arr = [],
tmp;
for(var i=0, l=old_arr.length; i<l; i++)
{
tmp = old_arr[i];
if( tmp !== '0' )
{
new_arr.push( tmp );
}
}
If you do splice, iterate backwards!
For ES6 best practice standards:
let a = ['0','567','956','0','34'];
a = a.filter(val => val !== "0");
(note that your "id's" are strings inside array, so to check regardless of type you should write "!=")
Below code can solve your problem
for(var i=0; i<ids.length;i++ )
{
if(ids[i]=='0')
ids.splice(i,1);
}
ids.filter(function(x) {return Number(x);});
I believe, the shortest method is
var newList = ['0', '567', '956', '0', '34'].filter(cV => cV != "0")
You could always do,
listWithZeros = ['0', '567', '956', '0', '34']
newList = listWithZeros.filter(cv => cv != "0")
The newList contains your required list.
Explanation
Array.prototype.filter()
This method returns a new array created by filtering out items after testing a conditional function
It takes in one function with possibly 3 parameters.
Syntax:
Array.prototype.filter((currentValue, index, array) => { ... })
The parameters explain themselves.
Read more here.
The easy approach is using splice!!. But there's a problem, every time you remove an element your array size will constantly reduce. So the loop will skip 1 index the array size reduces.
This program will only remove every first zero.
// Wrong approach
let num = [1, 0, 0, 2, 0, 0, 3,];
for(let i=0; i<num.length; i++){
if(num[i]==0)
num.splice(i, 1);
}
console.log(num)
the output will be
[1,0,2,0,3]
So to remove all the zeros you should increase the index if you found the non-zero number.
let i = 0;
while(i<num.length){
if(num[i]==0){
num.splice(i,1);
}
else{
i++;
}
}
But there's a better way. Since changing the size of the array only affects the right side of the array. You can just traverse in reverse and splice.
for(let i=num.length-1; i>=0; i--){
if(num[i]===0)
num.splice(i,1);
}

Categories

Resources