Array in javascript not printing as per key insertion order - javascript

Below is the code snippet.
Expected : The output of the alert must be:
210 then 202 then 201
Working currently :
201 then 202 and 210.
Issue is, I want in insertion order and not in sorted order.
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var newItem = new Array();
newItem['210'] = new Array(1,'test1');
newItem['202'] = new Array(2,'test1');
newItem['201'] = new Array(3,'test1');
for(var item in newItem) {
alert(item);
}
</script>
</body>
</html>

If you want to go with insertion order, and strings as keys, use a Map.
From the documentation
A Map object iterates its elements in insertion order — a for...of
loop returns an array of [key, value] for each iteration.
let newItem = new Map();
newItem.set('210', [1,'test1']);
newItem.set('202', [2,'test1']);
newItem.set('201', [3,'test1']);
for ( let item of newItem ) console.log(item);

A couple things - arrays have one value per index slot, like this:
[1,2,3,4]
What you're creating above is a key/value pair, which in JavaScript is an object - object keys have no sort order - so getting them in the order they were inserted just isn't going to happen. What you want is an array of objects
var arr = [];
var obj = { '201' : [1, 'test1'] }
//create the rest of your objects
arr.push(obj);
And another note, when you iterate an array, you use the regular for syntax - when you iterate an object, use for..in
for (var i = 0; i < arr.length; i++) {
var objKeys = Object.keys(arr[i]); //get the keys of the object being iterated over
console.log(objKeys[0]); //log the first key (since your objects only have 1 key
}

Use can set the key, that is "210", "202", "201" as the first element of the created array for each key; use Array.of() to set created arrays as element; iterate array created with Array.of() at for..of loop. Optionally utilize Array.prototype.entries() chained to created array to confirm index of created array containing key as first element within array.
let items = Array.of(["210", 1, "test1"]
, ["202", 2, "test1"]
, ["201", 3, "test1"]);
for (let [key, value] of items.entries()) {
// do stuff
console.log(key, value)
};

Below a very simple code example for what you are trying to achieve, based on your question's expected output.
var newItem = [];
newItem.push('210');
newItem.push('202');
newItem.push('201');
newItem.forEach( value => console.log(value) )

Related

Using Javascript 2D array duplicate record in one row by adding one property value with final array only unique record with modified properties

Question Array:
let array=[
["a23","3000","0","ES08"],
["a23","3000","0","ES93"],
["a23","3000","0","ES71"],
["12w","3007","0","ES34"],
["12w","3007","0","ES56"],
["1v8","3008","0","ES08"]
]
Condition:
Duplicate record constraints array[0][0]+array[0][1] equal to array[1][0]+array[1][1].....etc
Expected Result:
array= [
["a23","3000","0","ES08ES93ES71"],
["12w","3007","0","ES34ES56"],
["1v8","3008","0","ES08"]
]
Simple approach would be :
Group elements and accumulate last element (which contains different ES*) in an array:
{ "a2330000": [["ES08"], ["ES93"], ["ES71"]], "12w30070": [["ES34"], ["ES56"]], "1v830080": [["ES08"]], }
Loop again to get those accumulated ES* and join them back.
let array=[ ["a23","3000","0","ES08"], ["a23","3000","0","ES93"], ["a23","3000","0","ES71"], ["12w","3007","0","ES34"], ["12w","3007","0","ES56"], ["1v8","3008","0","ES08"] ];
let obj = {}
for (let arr of array) {
let key = arr.slice(0,-1).join('');
obj[key]??= [];
obj[key].push(arr.slice(-1));
}
let output = []
for (let arr of array) {
let key = arr.slice(0,-1).join('');
if(obj[key] && !obj[key].visited){
output.push([...arr.slice(0,-1),obj[key].join('')])
obj[key].visited = true;
}
}
console.log(output)
Note: I added visited property just to not create duplicate inner arrays of the same id key (combination of three first element of inner array)

How to send each player a list of players while excluding themselves from the list

Sorry for the confusing title.
If I have an array as ['Peter','James','Susan','Thomas'] and I want to get the array.length number of new arrays (in this case is 4), with each of the new array having one less different name of the original one.
So what I want is this 4 arrays:
['James','Susan','Thomas']
['Peter','Susan','Thomas']
['Peter','James','Thomas']
['Peter','James','Susan']
And if I want to sent each new array to person whose name is not there. (So I want to sent Peter ['James','Susan','Thomas'], and to James ['Peter','Susan','Thomas'].
My current code is:
for(var i=0;i<array.length;i++){
var player = array[i]
var newArray= array.splice(i,1)
io.to(player)emit('message', newArray)
}
The returned array only has one name in it.
The problem is that array.splice() modifies the original array. You need to make a copy of it first, so you don't destroy the original. You also shouldn't assign .splice to newArray, because it returns an array of the elements that were removed, not the modified array.
for (var i = 0; i < array.length; i++) {
var player = array[i];
var newArray = array.slice();
newArray.splice(i, 1);
io.to(player).emit('message', newArray);
}
Array#splice actually mutates the array it is called upon. The reason it can be confusing is that it also returns an array containing the elements you just deleted -- hence you receiving an array with a single item. Try using Array#forEach instead, and make a copy of your array using Array#slice before running splice so that the original array is not damaged with each iteration.
// For demo purposes
var io = { to: function(player) { return { emit: function(s, msg) { console.log(player, 'received', msg) } } } }
var array = ['Peter', 'James', 'Susan', 'Thomas']
array.forEach(function(player, i, a) {
(a = a.slice()).splice(i, 1)
io.to(player).emit('message', a)
})

Find duplicate object values in an array and merge them - JAVASCRIPT

I have an array of objects which contain certain duplicate properties: Following is the array sample:
var jsonData = [{x:12, machine1: 7}, {x:15, machine2:7},{x:12, machine2: 8}];
So what i need is to merge the objects with same values of x like the following array:
var jsonData = [{x:12, machine1:7, machine2:8}, {x:15, machine2:7}]
I like the lodash library.
https://lodash.com/docs#groupBy
_.groupBy(jsonData, 'x') produces:
12: [ {x=12, machine1=7}, {x=12, machine2=8} ],
15: [ {x=15, machine2=7} ]
your desired result is achieved like this:
var jsonData = [{x:12, machine1: 7}, {x:15, machine2:7},{x:12, machine2: 8}];
var groupedByX = _.groupBy(jsonData, 'x');
var result = [];
_.forEach(groupedByX, function(value, key){
var obj = {};
for(var i=0; i<value.length; i++) {
_.defaults(obj, value[i]);
}
result.push(obj);
});
I'm not sure if you're looking for pure JavaScript, but if you are, here's one solution. It's a bit heavy on nesting, but it gets the job done.
// Loop through all objects in the array
for (var i = 0; i < jsonData.length; i++) {
// Loop through all of the objects beyond i
// Don't increment automatically; we will do this later
for (var j = i+1; j < jsonData.length; ) {
// Check if our x values are a match
if (jsonData[i].x == jsonData[j].x) {
// Loop through all of the keys in our matching object
for (var key in jsonData[j]) {
// Ensure the key actually belongs to the object
// This is to avoid any prototype inheritance problems
if (jsonData[j].hasOwnProperty(key)) {
// Copy over the values to the first object
// Note this will overwrite any values if the key already exists!
jsonData[i][key] = jsonData[j][key];
}
}
// After copying the matching object, delete it from the array
// By deleting this object, the "next" object in the array moves back one
// Therefore it will be what j is prior to being incremented
// This is why we don't automatically increment
jsonData.splice(j, 1);
} else {
// If there's no match, increment to the next object to check
j++;
}
}
}
Note there is no defensive code in this sample; you probably want to add a few checks to make sure the data you have is formatted correctly before passing it along.
Also keep in mind that you might have to decide how to handle instances where two keys overlap but do not match (e.g. two objects both having machine1, but one with the value of 5 and the other with the value of 9). As is, whatever object comes later in the array will take precedence.
const mergeUnique = (list, $M = new Map(), id) => {
list.map(e => $M.has(e[id]) ? $M.set(e[id], { ...e, ...$M.get(e[id]) }) : $M.set(e[id], e));
return Array.from($M.values());
};
id would be x in your case
i created a jsperf with email as identifier: https://jsperf.com/mergeobjectswithmap/
it's a lot faster :)

How to access multidimensional array by index in javascript?

I have an array like below in java-script
Result = [
{"ID":1,"Type":"Pyramid","Phase":"One"},
{"ID":2,"Type":"Pyramid","Phase":"Two"}
]
I tried accessing the individual values and was able to by the below code
alert(Result[0].ID) or alert(Result[0].Phase)
Is there a way to access this by index? like Result[0][1], i tried but getting [object][object]
also i need to access column count
Please help me
You have array of object and by using for loop you can easily access all element value.
try following
function getValue() {
var keys ;
var Result = [{"ID":1,"Type":"Pyramid","Phase":"One"}, {"ID":2,"Type":"Pyramid","Phase":"Two"}]
for(var i=0; i<Result.length;i++){
keys = [];
for(var k in Result[i]){
keys.push(k);
}
for(var k=0;k<keys.length;k++){
console.log(keys[k]+"="+ Result[i][keys[k]]);
}
console.log("key count =" +keys.length);
}
}
CHECK THIS
from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
alert(Result[0][Object.keys(Result[0])[0]]);
Result[0] gets the first row
Object.keys(Result[0]) gets the keys in the first row
Object.keys(Result[0])[0] gets the first column name.
Object.keys(Result[0]).length is the column count in the first row.
Also, objects are not indexed based on a linear integer index as arrays are, so assigning ordered numbers to the unordered list of keys is not right.
A two dimensional array would look like this:
Result = [
[1,"Pyramid","One"],
{2,"Pyramid","Two"}
]
in this case, you could address each field like so: Result[row][col] thus Result[0][2] would yield One.
To access fields in an array of object use the syntax you have provided. Also, why would you want to access the fields in your objects based on id? Or why would you not use an array of arrays?
Your Result is an array of object, then you must first get an object, and then get the property of your object. This is not a multidimensional array.
You array has an object we have to convert that object to array. So converting whole var Result to newResult you can access newResult and it's component through index number
Result = [
{"ID":1,"Type":"Pyramid","Phase":"One"},
{"ID":2,"Type":"Pyramid","Phase":"Two"}
];
var newResult = [];
for (var i = 0; i < Result.length; i++) {
newResult[i] = [];
for (var x in Result[i]) {
if (Result[i].hasOwnProperty(x)) {
newResult[i].push(Result[i][x]);
}
};
};
console.log(newResult);
Use newResult instead of Result
You can get ID by newResult[0][0]
http://jsfiddle.net/LLz1cbok/

Adding to JSON array in JavaScript/jQuery

I have data being pulled in from various sources, each returning some form of JSON or similar, although, differently formatted each time. I need to get them all into one array, but I can't figure out how to do it.
The first set is an array like this:
[
Object {id="70", type="ab", dateadded="12345678"},
Object {id="85", type="ab", dateadded="87654321"}, ... more items ...
]
The second set is being pulled in from Facebook, and is like this:
[
Object {id="12341234234", created_time="12345678"},
Object {id="567856785678", created_time="87654321"}, ... more items ...
]
So, I need to alter the second set so that it has 'type', and it has 'dateadded' instead of 'created_time', and then I need to get this all into one array so it can be sorted on 'dateadded'.
How can I do this?
Use the first array's push() method:
// for each item in second array
firstArray.push(convert(item));
function convert(obj) {
// Convert obj into format compatible with first array and return it
}
Hope this helps.
Assuming you have actual valid JSON instead of what you quoted above:
var jsonOld = '[{"id":"70","type":"ab","dateadded":"12345678"},{"id":"85","type":"ab","dateadded":"87654321"}]',
jsonNew = '[{"id":"12341234234","created_time":"12345678"},{"id":"567856785678","created_time":"87654321"}]';
Then first parse these values into actual Javascript arrays:
var mainArr = JSON.parse(jsonOld),
newArr = JSON.parse(jsonNew);
(If you already have actual Javascript arrays instead of JSON strings then skip the above step.)
Then just iterate over newArr and change the properties you need changed:
for (var i = 0, il = newArr.length; i < il; i++) {
newArr[i].type = 'ab';
newArr[i].dateadded = newArr[i].created_time;
delete newArr[i].created_time;
}
And concatenate newArr into mainArr:
mainArr = mainArr.concat(newArr);
And sort on dateadded:
mainArr.sort(function(a, b) { return a.dateadded - b.dateadded; });
This will result in:
[{"id":"70","type":"ab","dateadded":"12345678"},
{"id":"12341234234","type":"ab","dateadded":"12345678"},
{"id":"85","type":"ab","dateadded":"87654321"},
{"id":"567856785678","type":"ab","dateadded":"87654321"}]
See example

Categories