How to group elements of array - javascript

I have an array:
var arr = ['User1','123456','User2','456789','User3','546544'];
How can I get array of object like this:
var arr2 = [{name: 'User1', id: 123456},{name: 'User2', id: 456789}, {name: 'User3', id: 546544}];
I tried this:
arr.forEach(function (item, i, arr) {
arr2.push(
{
name: arr[i],
id: arr[i + 2]
}
);
});

In a simple way, you need to do two things:
Check if the length is even.
Push it as how you require, by incrementing the loop twice.
var arr = ['User1', '123456', 'User2', '456789', 'User3', '546544'];
var arrObj = [];
if (arr.length % 2 === 0)
for (var i = 0; i < arr.length; i += 2)
arrObj.push({
"name": arr[i],
"id": parseInt(arr[i + 1], 10),
});
console.log(arrObj);

Look at the comments inside the code.
const arr = ['User1', '123456', 'User2', '456789', 'User3', '546544'];
// Ok, so what you to do is to group the infos and create a new object
// There is many function you can use, in the following example, I will use
// Array.reduce
// We gonna call couple, two values that goes together, like :
// User1 and 123456
// User2 and 456789
// ...
const ret = arr.reduce((tmp, x, xi) => {
// Add nothing for the first value of the couple
// We gonna ignore, User1, User2 and User3
if (xi % 2 === 0) return tmp;
return [
...tmp,
// Add a new value in the array
{
// The name is the first value of the couple
name: arr[xi - 1],
// The id is the second value of the couple
id: x,
},
];
}, []);
console.log(ret);

The for loop works on all versions of all computers and has the added advantage of being able to skip the index directly, something forEach can only do with a lot of extra code. Also forEach is slower than the for loop.
var arr1 = ['User1', '123456', 'User2', '456789', 'User3', '546544'], arr2 = [];
for (var i = 0; i < arr1.length - 1; i += 2) { // here is the i+=2
arr2.push({
"name": arr1[i],
"user": arr1[i + 1] // here is the i+1
});
}
console.log(arr2)
Or terser array
var arr1 = ['User1', '123456', 'User2', '456789', 'User3', '546544'], arr2 = [];
for (var i = 0; i < arr1.length - 1; i += 2) {
arr2.push({
[arr1[i]]: arr1[i + 1]
});
}
console.log(arr2)

A solution to your problem would be as follow :
var arr2 = [];
for (var i = 0; i < arr.length; i = i + 2) {
arr2.push({name : arr[i], id: arr[i + 1]})
}
Next time time try to show your trial code, you'll progress much more this way.

Related

How do i assign key / value pairs of an array of strings

let arr = ['drink', 'soda', 'name', 'john', 'someKey', 'someValue']
I'd like to assign key value pairs of the strings i have in the array above
for example:
[{drink: 'soda'},
{name: 'john'},
{someKey:'someValue'}
]
I've spent hours trying to figure this out... I've tried approaching it with the map method but my limited knowledge on javascript is consistently returning errors...
I'd really appreciate it if someone could help me out. Thanks
You can do it with a simple for loop:
let arr = ['drink', 'soda', 'name', 'john', 'someKey', 'someValue'];
let result = [];
for(let i = 0; i < arr.length; i+=2) {
let obj = {}
obj[arr[i]] = arr[i+1];
result.push(obj)
}
console.log(result)
A simple old-school loop increasing the step by 2 on each iteration.
Note: this will give you a single object with key/value pairs which makes (to my mind) a more useful data structure than an array of objects with one key/value pair each. If you're looking for an array of objects #sonEtLumiere's answer is the right one.
const arr = ['drink', 'soda', 'name', 'john', 'someKey', 'someValue'];
// Initialise empty object
const out = {};
// Loop over the array in steps of 2 so
// that we can access `i` (the key) and
// `i + 1` (the value) on each iteration
for (let i = 0; i < arr.length; i += 2) {
out[arr[i]] = arr[i + 1];
}
console.log(out);
console.log(out.drink);
console.log(out.name);
console.log(out.someKey);
That would be the easiest way:
const arr = ['drink', 'soda', 'name', 'john', 'someKey', 'someValue']
const obj = {}
for (let i = 0; i < arr.length; i += 2) {
obj[arr[i]] = arr[i + 1]
}
console.log(obj)
Or if you really want a oneliner
const arr = ['drink', 'soda', 'name', 'john', 'someKey', 'someValue']
const result = arr.reduce((fin, str, i, arr) => i & 1 ? fin : { ...fin, [str]: arr[i + 1] }, {})
console.log(result)

create object array based on max value in javascript

I would like to know how to create object array based on max value in javascript,
based on max value how to create object as shown
for(var i = 0; i<=max;i++){
var result = [];
result.push({id: `${i}`, name: `s${i}`});
return result;
}
var max = 20;
var obj = [{id: 0, name: ""}]
Expected Output
result = [
{id: 1, name: "s1"},
{id: 2, name: "s2"},
{id: 3, name: "s3"},
..
..
{id: 20, name: "s20"}
]
Firstly, if you want to return a value you'll need a function. Then you'll have to take the initialization of the array out of the for loop, otherwise you'll be initializing it with every iteration. Then you can push the new objects to the array and finally you can return the newly populated array, like so:
const createObjectArray = (max) => {
var result = [];
for (var i = 0; i <= max; i++) {
result.push({ id: `${i}`, name: `s${i}` });
}
return result;
}
var max = 20;
let result = createObjectArray(max);
console.log(result);

How to check if particular element in an array has duplicate?

There is a lot of examples that illustrate how to find duplicates in an array, but I can't find the simple one that checks if particular element has duplicate. Therefore, the array of strings is input and the output is Boolean that tells us if particular element has duplicate or not.
For example:
array = ['name1', 'name2', 'name3', 'name2']
I need a function that returns "false" if element in an array is not unique, and "true" if it is.
Here is a sample code , with which you can identify whether a particular element is duplicated in an array or not
const beasts = ["ant", "bison", "camel", "duck", "bison"];
const searchKey = "ant";
let index = beasts.indexOf(searchKey);
let isDuplicate = false;
if (index == -1) {
console.log("Element not present in array");
} else {
index = beasts.indexOf(searchKey, index + 1);
if (index > -1) {
isDuplicate = true;
}
}
console.log(isDuplicate);
## Solution 2
Convert array to set.
Set removes all duplicate records
array = ["name1", "name2", "name3", "name2"];
let set = new Set(array);
if (array.lenght === set.size) {
console.log("Unique array items");
} else {
console.log("Not unique array");
}
You can modify the code as per your needs.
const isUnique = (arr, x) => arr.filter(v => v === x).length <= 1
const x = [1, 2, 3, 1, 2, 3, 4, 5]
console.log(isUnique(x, 3), isUnique(x, 5))
How do you think about this?
function isUnique(arr) {
const hash = {}
for(const item of arr) {
hash[item] = (hash[item] || 0) + 1
if(hash[item] > 1) {
return false
}
}
return true
}
console.log(isUnique(['item1', 'item2', 'item1']))
console.log(isUnique(['item1', 'item2', 'item3']))
Try this. I hope this the solution you are trying to solve.
array1 = ['name1', 'name2', 'name3', 'name2'];
array2 = ['name1', 'name2', 'name3', 'name4'];
console.log(isUnique(array1));
console.log(isUnique(array2));
function isUnique(array) {
var valuesSoFar = [];
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (valuesSoFar.indexOf(value) !== -1) {
return false;
}
valuesSoFar.push(value);
}
return true;
}

Count number of times a word from one array occurs in a second array

So you have two arrays. Search the second array and count how many times each word from the first array occurs in the second one. Display a scrollable list of all the words from the second array and their counts from the first array. I don't want to show only the duplicate values so an intersection function wouldn't help .Use only javascript.
Ex:
listOne = [Pat, cat, hat, Tat, bat, rat];
listTwo = [Pat, mat, sat, rat, cat, Tat, Pat];
And the output would be as follows:
Pat: 2
mat: 0
sat: 0
rat: 1
cat: 1
Tat: 1
I have tried multiple ways and the closest I came up with is this:
function findFreq(listOne, listTwo, concatList) {
var a = [], b = [], lookup = {}, prev;
for(var j = 0; j < listTwo.length; j++) {
lookup[listTwo[j]] = listTwo[j];
}
for (var i = 0; i < concatList.length; i++ ) {
if (concatList[i] !== prev) {
a.push(lookup[concatList[i]]);
b.push(0);
} else {
b[b.length - 1]++;
}
prev = concatList[i];
}
return [a, b];
}
var result = findFreq(listOne, listTwo, concatList);
alert('[' + result[0] + ']<br />[' + result[1] + ']');
As you can see I thought concating the two arrays would be easiest because all of the examples I found of counting the occurrence of elements only dealt with a single array. In fact I took the code from here and tried modifying it to fit my needs.
The problem is the output gives me empty or extra elements.
[Pat,Tat,,cat,,mat,rat,sat]
[2,1,0,1,0,0,1,0]
So the answer is wrong and so is the formatting. I'm probably over complicating this. It is probably easier to compare the two arrays directly, but I just can't figure it out. Any help would be appreciated.
Note: For my program the two arrays I'm using actually come from user specified files that I just use the split() function on. That's why my naming conventions are strange.
Just loop over both arrays. Something like this should work:
listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];
for(var i = 0; i < listOne.length; i++) {
matches = 0;
for(var j = 0; j < listTwo.length; j++) {
if(listOne[i] == listTwo[j]) {
matches++;
}
}
console.log(listOne[i] + ' has '+ matches+ ' occurance(s)')
}
You can see it working here: https://jsfiddle.net/igor_9000/9n883kse/
Hope that helps!
Using Array.prototype.map() to create array of counts, Array.prototype.reduce() to do counting
listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];
var res = listOne.map(function(word) {
return listTwo.reduce(function(count, test) {
return word === test ? ++count : count;
}, 0);
});
document.getElementById('pre').innerHTML =JSON.stringify(res)
console.log(res)//[2,1,0,1,0,1]
<pre id="pre"></pre>
You can create a cycle for the first list and compare all the elements of the second list to each element of the first list to see if they exist and if so, how often repeated.
var listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
var listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];
function findFreq(listOne, listTwo) {
var a = [], b = [], flag = false, cache = 0;
for(var i=0; i<listOne.length; i++){
var temp = listOne[i];
for(var j=0; j<listTwo.length; j++){
if(temp === listTwo[j]){
cache++;
}
}
if(cache!=0){
a.push(temp);
b.push(cache);
cache=0;
}
}
return [a,b];
}
var result = findFreq(listOne, listTwo);
for(var k=0; k<result[0].length; k++){
console.log(result[0][k] + ': ' + result[1][k]);
}
var listOne = 'pat, cat, hat, tat, bat, rat'.split(', ');
var listTwo = 'pat, mat, sat, rat, cat, tat, pat'.split(', ');
// “Count how many times each word from the first array occurs in the second one.”
var results = listOne
.reduce(function(prev, current) {
if(!prev[current]) {
prev[current] = (prev[current] || 0)
+ listTwo.filter(function(item) { return current === item; }).length;
}
return prev;
}, {});
Returns
{
"pat": 2,
"cat": 1,
"hat": 0,
"tat": 1,
"bat": 0,
"rat": 1
}
Then you could build HTML as a string, for example,
var htmlStr = Object.keys(results)
.map(function(key) {
return '<tr><td>'+key+'</td><td>'+results[key]+'</td></tr>';
})
.join('\r');
which would yield
'<tr><td>pat</td><td>2</td></tr>
<tr><td>cat</td><td>1</td></tr>
<tr><td>hat</td><td>0</td></tr>
<tr><td>tat</td><td>1</td></tr>
<tr><td>bat</td><td>0</td></tr>
<tr><td>rat</td><td>1</td></tr>'
(I’ve been fast and loose with my line breaks, but you get the idea.)
take a further look at the documentation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
function myCounter(listOne, listTwo) {
return [listOne, listTwo].reduce(function(a, b) {
return a.concat(b);
}, []).reduce( (countWords, word) => {
countWords[word] = ++countWords[word] || 0;
return countWords;
}, {});
}
var listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
var listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];
console.log(myCounter(listOne, listTwo));
Maybe it helps you!

How to replace item in array?

Each item of this array is some number:
var items = Array(523,3452,334,31, ...5346);
How to replace some item with a new one?
For example, we want to replace 3452 with 1010, how would we do this?
var index = items.indexOf(3452);
if (index !== -1) {
items[index] = 1010;
}
Also it is recommend you not use the constructor method to initialize your arrays. Instead, use the literal syntax:
var items = [523, 3452, 334, 31, 5346];
You can also use the ~ operator if you are into terse JavaScript and want to shorten the -1 comparison:
var index = items.indexOf(3452);
if (~index) {
items[index] = 1010;
}
Sometimes I even like to write a contains function to abstract this check and make it easier to understand what's going on. What's awesome is this works on arrays and strings both:
var contains = function (haystack, needle) {
return !!~haystack.indexOf(needle);
};
// can be used like so now:
if (contains(items, 3452)) {
// do something else...
}
Starting with ES6/ES2015 for strings, and proposed for ES2016 for arrays, you can more easily determine if a source contains another value:
if (haystack.includes(needle)) {
// do your thing
}
The Array.indexOf() method will replace the first instance. To get every instance use Array.map():
a = a.map(function(item) { return item == 3452 ? 1010 : item; });
Of course, that creates a new array. If you want to do it in place, use Array.forEach():
a.forEach(function(item, i) { if (item == 3452) a[i] = 1010; });
Answer from #gilly3 is great.
Replace object in an array, keeping the array order unchanged
I prefer the following way to update the new updated record into my array of records when I get data from the server. It keeps the order intact and quite straight forward one liner.
users = users.map(u => u.id !== editedUser.id ? u : editedUser);
var users = [
{id: 1, firstname: 'John', lastname: 'Ken'},
{id: 2, firstname: 'Robin', lastname: 'Hood'},
{id: 3, firstname: 'William', lastname: 'Cook'}
];
var editedUser = {id: 2, firstname: 'Michael', lastname: 'Angelo'};
users = users.map(u => u.id !== editedUser.id ? u : editedUser);
console.log('users -> ', users);
My suggested solution would be:
items.splice(1, 1, 1010);
The splice operation will start at index 1, remove 1 item in the array (i.e. 3452), and will replace it with the new item 1010.
Use indexOf to find an element.
var i = items.indexOf(3452);
items[i] = 1010;
First method
Best way in just one line to replace or update item of array
array.splice(array.indexOf(valueToReplace), 1, newValue)
Eg:
let items = ['JS', 'PHP', 'RUBY'];
let replacedItem = items.splice(items.indexOf('RUBY'), 1, 'PYTHON')
console.log(replacedItem) //['RUBY']
console.log(items) //['JS', 'PHP', 'PYTHON']
Second method
An other simple way to do the same operation is :
items[items.indexOf(oldValue)] = newValue
Easily accomplished with a for loop.
for (var i = 0; i < items.length; i++)
if (items[i] == 3452)
items[i] = 1010;
If using a complex object (or even a simple one) and you can use es6, Array.prototype.findIndex is a good one. For the OP's array, they could do,
const index = items.findIndex(x => x === 3452)
items[index] = 1010
For more complex objects, this really shines. For example,
const index =
items.findIndex(
x => x.jerseyNumber === 9 && x.school === 'Ohio State'
)
items[index].lastName = 'Utah'
items[index].firstName = 'Johnny'
You can edit any number of the list using indexes
for example :
items[0] = 5;
items[5] = 100;
ES6 way:
const items = Array(523, 3452, 334, 31, ...5346);
We wanna replace 3452 with 1010, solution:
const newItems = items.map(item => item === 3452 ? 1010 : item);
Surely, the question is for many years ago and for now I just prefer to use immutable solution, definitely, it is awesome for ReactJS.
For frequent usage I offer below function:
const itemReplacer = (array, oldItem, newItem) =>
array.map(item => item === oldItem ? newItem : item);
A functional approach to replacing an element of an array in javascript:
const replace = (array, index, ...items) => [...array.slice(0, index), ...items, ...array.slice(index + 1)];
The immutable way to replace the element in the list using ES6 spread operators and .slice method.
const arr = ['fir', 'next', 'third'], item = 'next'
const nextArr = [
...arr.slice(0, arr.indexOf(item)),
'second',
...arr.slice(arr.indexOf(item) + 1)
]
Verify that works
console.log(arr) // [ 'fir', 'next', 'third' ]
console.log(nextArr) // ['fir', 'second', 'third']
Replacement can be done in one line:
var items = Array(523, 3452, 334, 31, 5346);
items[items.map((e, i) => [i, e]).filter(e => e[1] == 3452)[0][0]] = 1010
console.log(items);
Or create a function to reuse:
Array.prototype.replace = function(t, v) {
if (this.indexOf(t)!= -1)
this[this.map((e, i) => [i, e]).filter(e => e[1] == t)[0][0]] = v;
};
//Check
var items = Array(523, 3452, 334, 31, 5346);
items.replace(3452, 1010);
console.log(items);
var items = Array(523,3452,334,31,5346);
If you know the value then use,
items[items.indexOf(334)] = 1010;
If you want to know that value is present or not, then use,
var point = items.indexOf(334);
if (point !== -1) {
items[point] = 1010;
}
If you know the place (position) then directly use,
items[--position] = 1010;
If you want replace few elements, and you know only starting position only means,
items.splice(2, 1, 1010, 1220);
for more about .splice
The easiest way is to use some libraries like underscorejs and map method.
var items = Array(523,3452,334,31,...5346);
_.map(items, function(num) {
return (num == 3452) ? 1010 : num;
});
=> [523, 1010, 334, 31, ...5346]
If you want a simple sugar sintax oneliner you can just:
(elements = elements.filter(element => element.id !== updatedElement.id)).push(updatedElement);
Like:
let elements = [ { id: 1, name: 'element one' }, { id: 2, name: 'element two'} ];
const updatedElement = { id: 1, name: 'updated element one' };
If you don't have id you could stringify the element like:
(elements = elements.filter(element => JSON.stringify(element) !== JSON.stringify(updatedElement))).push(updatedElement);
var index = Array.indexOf(Array value);
if (index > -1) {
Array.splice(index, 1);
}
from here you can delete a particular value from array and based on the same index
you can insert value in array .
Array.splice(index, 0, Array value);
Well if anyone is interresting on how to replace an object from its index in an array, here's a solution.
Find the index of the object by its id:
const index = items.map(item => item.id).indexOf(objectId)
Replace the object using Object.assign() method:
Object.assign(items[index], newValue)
items[items.indexOf(3452)] = 1010
great for simple swaps. try the snippet below
const items = Array(523, 3452, 334, 31, 5346);
console.log(items)
items[items.indexOf(3452)] = 1010
console.log(items)
Here is the basic answer made into a reusable function:
function arrayFindReplace(array, findValue, replaceValue){
while(array.indexOf(findValue) !== -1){
let index = array.indexOf(findValue);
array[index] = replaceValue;
}
}
Here's a one liner. It assumes the item will be in the array.
var items = [523, 3452, 334, 31, 5346]
var replace = (arr, oldVal, newVal) => (arr[arr.indexOf(oldVal)] = newVal, arr)
console.log(replace(items, 3452, 1010))
const items = Array(1, 2, 3, 4, 5);
console.log(items)
items[items.indexOf(2)] = 1010
console.log(items)
First, rewrite your array like this:
var items = [523,3452,334,31,...5346];
Next, access the element in the array through its index number. The formula to determine the index number is: n-1
To replace the first item (n=1) in the array, write:
items[0] = Enter Your New Number;
In your example, the number 3452 is in the second position (n=2). So the formula to determine the index number is 2-1 = 1. So write the following code to replace 3452 with 1010:
items[1] = 1010;
I solved this problem using for loops and iterating through the original array and adding the positions of the matching arreas to another array and then looping through that array and changing it in the original array then return it, I used and arrow function but a regular function would work too.
var replace = (arr, replaceThis, WithThis) => {
if (!Array.isArray(arr)) throw new RangeError("Error");
var itemSpots = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] == replaceThis) itemSpots.push(i);
}
for (var i = 0; i < itemSpots.length; i++) {
arr[itemSpots[i]] = WithThis;
}
return arr;
};
presentPrompt(id,productqty) {
let alert = this.forgotCtrl.create({
title: 'Test',
inputs: [
{
name: 'pickqty',
placeholder: 'pick quantity'
},
{
name: 'state',
value: 'verified',
disabled:true,
placeholder: 'state',
}
],
buttons: [
{
text: 'Ok',
role: 'cancel',
handler: data => {
console.log('dataaaaname',data.pickqty);
console.log('dataaaapwd',data.state);
for (var i = 0; i < this.cottonLists.length; i++){
if (this.cottonLists[i].id == id){
this.cottonLists[i].real_stock = data.pickqty;
}
}
for (var i = 0; i < this.cottonLists.length; i++){
if (this.cottonLists[i].id == id){
this.cottonLists[i].state = 'verified';
}
}
//Log object to console again.
console.log("After update: ", this.cottonLists)
console.log('Ok clicked');
}
},
]
});
alert.present();
}
As per your requirement you can change fields and array names.
thats all. Enjoy your coding.
The easiest way is this.
var items = Array(523,3452,334,31, 5346);
var replaceWhat = 3452, replaceWith = 1010;
if ( ( i = items.indexOf(replaceWhat) ) >=0 ) items.splice(i, 1, replaceWith);
console.log(items);
>>> (5) [523, 1010, 334, 31, 5346]
When your array have many old item to replace new item, you can use this way:
function replaceArray(array, oldItem, newItem) {
for (let i = 0; i < array.length; i++) {
const index = array.indexOf(oldItem);
if (~index) {
array[index] = newItem;
}
}
return array
}
console.log(replaceArray([1, 2, 3, 2, 2, 8, 1, 9], 2, 5));
console.log(replaceArray([1, 2, 3, 2, 2, 8, 1, 9], 2, "Hi"));
let items = Array(523,3452,334,31, 5346);
items[0]=1010;
This will do the job
Array.prototype.replace = function(a, b) {
return this.map(item => item == a ? b : item)
}
Usage:
let items = ['hi', 'hi', 'hello', 'hi', 'hello', 'hello', 'hi']
console.log(items.replace('hello', 'hi'))
Output:
['hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi']
The nice thing is, that EVERY array will have .replace() property.

Categories