How to jumble JSON.parse data? [duplicate] - javascript

This question already has answers here:
How to randomize (shuffle) a JavaScript array?
(69 answers)
How can I shuffle an array? [duplicate]
(2 answers)
Closed 4 days ago.
This post was edited and submitted for review 16 hours ago and failed to reopen the post:
Original close reason(s) were not resolved
Is it possible to shuffle a json parsed result from ajax?
$.ajax({
method: 'GET',
url: '/-pathSomething-/--ExampleOnly--',
data: { sample: sample, sample: sample, sample: sample },
success: function (result) {
var ExamDislayQNChoiceML = JSON.parse(result);
}
});
it is looks like this
i don't know how to do it so i don't have much code to show..
expected output.
randomly
{ QuesNo: 3, QuesID: 3, ... }
{ QuesNo: 1, QuesID: 1, ... }
{ QuesNo: 4, QuesID: 4, ... }
{ QuesNo: 2, QuesID: 2, ... }
{ QuesNo: 5, QuesID: 5, ... }

use the Fisher-Yates shuffle algorithm here is a documentation link: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle and Here's an example of how use it to shuffle the array of objects
$.ajax({
method: 'GET',
url: '/-pathSomething-/--ExampleOnly--',
data: { sample: sample, sample: sample, sample: sample },
success: function (result) {
var ExamDislayQNChoiceML = JSON.parse(result);
shuffleArray(ExamDislayQNChoiceML);
console.log(ExamDislayQNChoiceML); // shuffled array
}
});
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

this could do your request
let myJSON = {
"name": "John",
"age": 30,
"city": "New York"
};
let myArray = Object.entries(myJSON);
for (let i = myArray.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[myArray[i], myArray[j]] = [myArray[j], myArray[i]];
}
myJSON = Object.fromEntries(myArray);
console.log(myJSON);
This will be the output
{
"city": "New York",
"name": "John",
"age": 30
}

Assuming that you wanted to shuffle array of questions objects: You can pass Math.random() to Array.sort() method. Math.random() returns float between 0 and 1. When you subtract 0.5 from result of Math.random(), the Array.sort() compare function returns random positive or negative value, so the array is shuffled:
const shuffleArray = arr => arr.sort(() => Math.random() - 0.5);
const shuffledArr = shuffleArray(arr);

Related

Iterate over Array and replacing at a certain value

I have a question about feasibility of my code. I'm sure there is a better and more efficient way to write the function I wrote.
This is the function:
let i;
for (i = 0; i < ns.length; i++) {
if (ns[i] > 1) {
ns[i] = 3;
const place = ns[i];
ns.splice(place + 2, 1, 4);
ns.splice(place, 1, 2);
ns.splice(place - 1, 1, 1);
}
}
Initial Array (this array have a length of upto 20 items):
ns = [1 , 1 , 1 , 1 , 2 , 0]
Result Array:
ns = [1 , 1 , 1 , 2 , 3 , 4]
Believe it or not but this will suit my needs. But is there a better way than to just add up three times splice? It also extends my array if the number two of the initial array is at the end or beginning. I know I could just wrap it in another conditional but this seems so clumsy to me.
Thanks in Advance!
Regards
You could replace splicing with deleting a single value and adding a single value with a simple assingment at the index.
For preventing updating values at not given indices, you could take a function which checks the wanted index and updates only given indices.
function update(array, index, value) {
if (index >= 0 && index < array.length) {
array[index] = value;
}
}
var ns = [1, 1, 1, 1, 2, 0],
length = ns.length,
i,
place = 3;
for (i = 0; i < length; i++) {
if (ns[i] > 1) {
ns[i] = place;
update(ns, place - 1, 1);
update(ns, place, 2);
update(ns, place + 2, 4);
}
}
console.log(ns);
So with help from Nina Scholz and a Friend i got to the right answer:
Initial Array:
["1", "1", "1", "1", "1", "2", "0", "0"]
Desired Array:
["1", "1", "1", "1", "2", "3", "4", "0"]
The Function:
isSibling() {
const siblings = this.props.data.map(item => (
item.progress
));
let i;
const place = '3';
for (i = 0; i < siblings.length; i++) {
if (siblings[i] === '2') {
const num = i;
siblings[i] = place;
this.update(siblings, i - 1, '2');
this.update(siblings, i + 1, '4');
return siblings;
}
}
return siblings;
}
Update Function:
to ensure the array is not enlongated or shortened:
update(array, index, value) {
if (index >= 0 && index < array.length) {
array[index] = value;
}
}
Thank you for your help! :D

Get random element from array with weighted elements [duplicate]

This question already has answers here:
Weighted random selection from array
(15 answers)
Closed 6 years ago.
I have an array of objects that represent creatures in a game I'm trying to develop. These objects have (among others) a unique identifier and a weight (or probability) to spawn.
I'm trying to develop an algorithm to spawn creatures randomly but I fail to come up with a way to use the weights (I really don't know how to do it).
Can anybody help?
An example of creatures array could be:
var creatures = [
{id: 1, weight: 25},
{id: 2, weight: 15},
{id: 3, weight: 5},
{id: 4, weight: 45},
{id: 5, weight: 10}
]
I found this nice algorithm implemented in PHP in this blog that I think migth suit your needs.
I just adopted it to JS.
var creatures = [{
id: 1,
weight: 25
}, {
id: 2,
weight: 15
}, {
id: 3,
weight: 5
}, {
id: 4,
weight: 45
}, {
id: 5,
weight: 10
}],
sumOfWeights = creatures.reduce(function(memo, creature) {
return memo + creature.weight;
}, 0),
selectedWeigths = {};
function getRandom(sumOfWeights) {
var random = Math.floor(Math.random() * (sumOfWeights + 1));
return function(creature) {
random -= creature.weight;
return random <= 0;
};
}
for (var i = 0; i < 1000; i++) {
var creature = creatures.find(getRandom(sumOfWeights));
selectedWeigths[creature.weight] = (selectedWeigths[creature.weight] || 0) + 1;
}
console.log(selectedWeigths);
Hope it helps.
Create a new array and add the id for each creature to the array the number of times it is weighted. Then get a random number between 0 and the size of the array and return the id number at that position.
var creatureIds = [];
for(var i=0;i<creatures.length;i++){
for(var x=0;x<creatures[i].weight;x++){
creatureIds.push(creatures[i].id);
}
}
// get a random index between 0 and the ids length.
var min = 0;
var max = creatureIds.length;
var index = Math.floor(Math.random() * (max - min + 1)) + min;
var randomWeightedCreatureId = creatureIds[index];

Javascript: Most Efficient Way of Summing Multiple Arrays by Key

I have a JSON object returned from a web service, which is an array of objects. I need to add the "data" arrays together to form a summed array. The JSON response looks like this:
[
{
"data":[
0,3,8,2,5
],
"someKey":"someValue"
},
{
"data":[
3,13,1,0,5
],
"someKey":"someOtherValue"
}
]
There could be N amount of objects in the array. The desired output for the above example would be:
[3, 16, 9, 2, 10]
I was intending on creating an empty array variable (var arr), then looping over the objects, and for each object, loop through the "data" key and for each key increment the corresponding key in arr by the value.
Is there a more efficient way of doing this using some sort of merge function?
How about this, I believe it should work for all cases.
var data = [{
"data": [
0, 3, 8, 2, 5
],
"someKey": "someValue"
}, {
"data": [
3, 13, 1, 0, 5
],
"someKey": "someOtherValue"
}];
var datas = data.reduce(function(a, b) {
b.data.forEach(function(x, i) {
a[i] = a[i] || 0;
a[i] += x;
});
return a;
}, []);
console.log(datas);
If every object has the same data length, you can try with:
var input; // Your input data
var output = [];
for (var i = 0; i < input[0].data.length; i++) {
output[i] = input.reduce(function(prev, item) {
return +(item.data[i]) + prev;
}, 0);
}
console.log(output);
// [3, 16, 9, 2, 10]
If every object has different data size:
var input; // Your input data
var i = 0, output = [];
while (true) {
var outOfIndex = true;
var sum = input.reduce(function(prev, item) {
if (item.data[i] !== undefined) {
outOfIndex = false;
}
return +(item.data[i]) + prev;
}, 0);
if (outOfIndex) {
break;
}
output[i++] = sum;
}
console.log(output);
// [3, 16, 9, 2, 10]
Slightly less imperative solution:
//zip takes two arrays and combines them per the fn argument
function zip(left, right, fn) {
var shorter = (right.length > left.length) ? left : right;
return shorter.map(function(value, i) {
return fn(left[i], right[i]);
});
}
//assuming arr is your array of objects. Because were using
//zip, map, and reduce, it doesn't matter if the length of the
//data array changes
var sums = arr
.map(function(obj) { return obj.data; })
.reduce(function(accum, array) {
//here we want to combine the running totals w/the current data
return zip(accum, array, function(l, r) { return l + r; });
});

Sorting for array not working properly with Internet Explorer 10 and firefox

I need to sort array . But i am not getting desired result on internet explorer.
var s = [1,2,3,4,2,1,2,8,0,5];
var y = _.sortBy(s,function(item1, item2) { return (item1 < item2); });
o/p: [object Array][1, 2, 3, 4, 8, 2, 1, 2, 0, 5]
Also tried :
var y = s.sort(function(item1, item2) { return (item1 < item2); });
o/p object Array][1, 2, 3, 4, 2, 1, 2, 8, 0, 5]
with InternetExplorer 10 , i am not getting sorted array. any idea .
var y = s.sort(function(item1, item2) { return (item1 < item2); });
working fine on chrome and mozilla? but not
var y = _.sortBy(s,function(item1, item2) { return (item1 < item2); });
This is working with just chrome.
Same sorting concept i am using to sort json array , eg.
var employees = [
{"firstName":"John", "lastName":"Doe", "age": 23},
{"firstName":"Anna", "lastName":"Smith", "age": 12},
{"firstName":"Peter","lastName":"Jones", "age": 5},
{"firstName":"John1", "lastName":"Doe1", "age": 3},
{"firstName":"John2", "lastName":"Doe2", "age": 13},
];
var y = employee.sort(function(item1, item2) {
var age1 = item1.age;
var age2 = item2.age;
return (age1< age2); });
}
Not getting desired result, as mentioned above
There are a number of problems with the snippets in the question:
The function that you pass to the Javascript array sort function is expected to return a number and not a boolean. If item1 comes before item2 then return a negative number, if item1 comes after item2 return a positive number and if item1 and item2 should remain where they are in the array then return 0. So in your example you could change the comparison in the function from return item1 < item2 to return item1 - item2.
The function passed to Underscore's sortBy in your example should take a single parameter. The value of the parameter will be each item in the array being sorted. The function is expected to return a value which will be used to rank the item in the array. Underscore can also take the name of a property whose value is used for the sort.
To sort employees by age you could do any of the the following:
var sorted = _.sortBy(employees, 'age');
var sorted = _.sortBy(employees, function(e){
return e.age;
});
var sorted = employees.sort( function(e1,e2){
return e1.age - e2.age;
});
I followed this approach and got correct response on all 3 browsers.:
var y = s.sort(function(count1, count2) {
if (count1 < count2) {
return 1;
} else if (count1 > count2) {
return -1;
}
return 0;
});

Sort object by value

So here's the object:
As you can see, the last amount(2000) is lower than 10000 but it's still at the end. I'm trying to display the elements sorted by amount. I know that I have to convert the object to array and use sort on it, but don't have an idea how can I do this properly.
EDIT: I've tried something like this without any success:
var packs_array = [];
jQuery.each(json.purchase_packs, function(i, pack) {
packs_array.push(pack);
});
packs_array.sort();
var packs = {
0: { amount: 2000 },
3: { amount: 1000 },
5: { amount: 50 }
};
var sortedPacks = Object.keys(packs)
.map(function (id) {
packs[id].id = parseInt(id, 10);
return packs[id];
})
.sort(function (a, b) {
return a.amount - b.amount;
});
console.log(sortedPacks); // => [{"amount":50,"id":5},{"amount":1000,"id":3},{"amount":2000,"id":0}]
To do this, you need to convert your object into an array first...
var arr = $.map(json.purchase_packs, function(v) { return v; });
... then sort this array with a custom sorter function:
arr.sort(function(a, b) {
return a.amount - b.amount;
});
Demo. Note that sorting is in-place operation (i.e., arr.sort alters an existing object).
JavaScript sort() function works with list elements as strings by default. You should specify sort function to sort other value types:
var l = [1, 5, 12, 127, 12, 3, 9];
l.sort(function(a,b){return a-b});
=> [ 1, 3, 5, 9, 12, 12, 127 ]
Source

Categories