Why my array getting appended instead of clearing and Adding new data - arrays

I am trying to achieve a method in which the array steps got filled with new data every time I click on the button of Create New array, but instead of that, the data is getting appended instead of updating.
here are my states :
const [arr , setArray] = useState(createArray())
const [steps , setSteps] = useState([]);
const [selectedAlgorithm , setSelectedAlgorithm] = useState ();
here is my create new Array function :
const handleCreateNewData = ()=>{
let newarr = createArray();
setArray ([]);
setArray([...newarr]);
setSteps ([]);
setTimeout(()=>{
if ( algorithms[selectedAlgorithm] !== undefined){
algorithms[selectedAlgorithm](arr, steps , setSteps);
console.log('running')
}
},2000)
}
here is my bubble sort algorithm :
export const BubbleSort = (array , steps ,setSteps) =>{
let funarray = new Array();
funarray = [...array] ;
for (let i = 0 ; i < funarray.length-1 ; i++){
for(let j = 0 ; j < funarray.length-1 ; j++){
if(funarray[j]>funarray[j+1]){
[funarray[j],funarray[j+1]] = [funarray[j+1],funarray[j]]
setSteps([...steps, funarray])
steps.push(funarray.slice());
console.log('Working')
}
}
}
return funarray;
}
What is supposed to do is every time I click on create new array it should generate a new set of arrays but instead of creating new arrays it just appending the new arrays in the old steps.

You can create a temp array to hold the steps, then when the loops are done, call setSteps:
const BubbleSort = (array, steps, setSteps) => {
let funarray = [];
funarray = [...array];
let temp = [];
for (let i = 0; i < funarray.length - 1; i++) {
for (let j = 0; j < funarray.length - 1; j++) {
if (funarray[j] > funarray[j + 1]) {
[funarray[j], funarray[j + 1]] = [funarray[j + 1], funarray[j]];
temp.push(funarray)
}
}
}
setSteps(temp);
return funarray;
};
Sample: https://codesandbox.io/s/cool-wind-ijj7z?file=/src/App.js

Related

how to shuffle an array except for the item in the middle?

Iยดm creating a Bingo board and I need that the one in the middle always stays the same even when shuffleing this array:
const bbb = [
"๐Ÿ˜‹",
"๐Ÿ˜",
"๐Ÿคฃ",
"๐Ÿ˜ƒ",
"๐Ÿ˜„",
"๐Ÿ˜…",
"๐Ÿ˜†",
"๐Ÿ˜‰",
"๐Ÿ˜Š",
"๐Ÿ˜Š",
"๐Ÿ˜Ž ",
"๐Ÿคฉ",
"๐ŸŽฏ",
"๐Ÿ˜ถ",
"๐Ÿ˜ซ",
"๐Ÿ˜ด",
"๐Ÿค ",
"๐Ÿ™„ ",
"๐Ÿ˜‘",
"๐Ÿ˜ฏ",
"๐Ÿ˜š",
"๐Ÿ˜ฅ",
"๐Ÿ˜ฎ ",
"๐Ÿ˜›",
"๐Ÿ˜"
];
const data = arrayShuffle(bbb).reduce(
(data, value, index) => ({ ...data, [index]: value }),
{}
);
and then Im maping the array to display the Tiles and create the board like this:
{Object.keys(data).map(id => (
<Tile
key={id}
id={id}
isSet={state.checked[id]}
onToggle={() => toggle(id)}
>
{data[id]}
</Tile>
))}
Remove the middle item from the array initially. Then do the in-place randomizing of items and finally attach the middle item to the array.
This runs in O(n) time complexity where n is the size of your array and you always get a uniform random permutation.
const bbb = [ "๐Ÿ˜‹", "๐Ÿ˜", "๐Ÿคฃ", "๐Ÿ˜ƒ", "๐Ÿ˜„", "๐Ÿ˜…", "๐Ÿ˜†", "๐Ÿ˜‰", "๐Ÿ˜Š", "๐Ÿ˜Š", "๐Ÿ˜Ž", "๐Ÿคฉ", "๐ŸŽฏ", "๐Ÿ˜ถ", "๐Ÿ˜ซ", "๐Ÿ˜ด", "๐Ÿค", "๐Ÿ™„", "๐Ÿ˜‘", "๐Ÿ˜ฏ", "๐Ÿ˜š", "๐Ÿ˜ฅ", "๐Ÿ˜ฎ", "๐Ÿ˜›", "๐Ÿ˜", ];
const getRandomInt = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
};
const arrayShuffleInplaceExceptMiddle = (A) => {
const middle = A.splice(A.length/2, 1);
const n = A.length;
const middleIndex = Math.floor(n / 2);
for (let i = 0; i < n; i++) {
let swapIndex = getRandomInt(i, n);
let a = A[i];
A[i] = A[swapIndex];
A[swapIndex] = a;
}
A.splice(n/2, 0, ...middle)
};
// test runs
Array.from({length: 10}, () => {
arrayShuffleInplaceExceptMiddle(bbb);
console.log(bbb.join(""));
})
Just shuffle the array normally, but remove the the value before the shuffle and insert it back afterward:
/**
* Durstenfeld shuffle
*
* - https://stackoverflow.com/a/12646864/438273
* - https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
*
* #param {unknown[]} 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]];
}
}
/**
* Like a normal shuffle, but for a bingo board
*
* #param {unknown[]} array
*/
function bingoShuffle (array) {
const index = Math.floor((array.length - 1) / 2);
const [value] = array.splice(index, 1);
shuffleArray(array);
array.splice(index, 0, value);
}
// Let's keep the board small for this demo:
const board = [
"๐Ÿ˜Š",
"๐Ÿ˜Š",
"๐Ÿ˜Ž",
"๐Ÿคฉ",
"๐ŸŽฏ",
"๐Ÿ˜ถ",
"๐Ÿ˜ซ",
"๐Ÿ˜ด",
"๐Ÿค",
];
console.log(board.join(' '));
// Shuffle it a few times and look at the results:
for (let i = 0; i < 10; i += 1) {
bingoShuffle(board);
console.log(board.join(' '));
}
And because you tagged this with reactjs, I'm guessing this is (immutable) state, so you'll need to get a new array when shuffling, like this:
const updatedBoard = bingoShuffle([...board]);
// ^^^^^^^^^^
// Shallow copy into new array so you don't mutate React state

Output variables one by one from array

how do I pull variables from array one by one? I want to make a card with one saying Zlin, second Praha, etc... The way it works now is that it outputs all of them at once 4x. Thank you.
const KartyLoop = () => {
var mesta = ['Zlin','Praha','Ostrava','Brno']
var lokace = []
for (var i=0; i < mesta.length; i++)
{
lokace += mesta + "\n"
}
return (<Text>{lokace}</Text>);
}
Your code pushes the array itself and not its values.
If I understand correctly you want to copy an array.
You would want to do this.
const KartyLoop = () => {
var mesta = ['Zlin','Praha','Ostrava','Brno']
var lokace = []
for (var i=0; i < mesta.length; i++)
{
lokace += mesta[i] + "\n"
}
return (lokace);
}

Combining a loop function and IF condition in google app scirpt

New to google app script and trying to create a function which combines loop (can be map, for or forEach) and IF condition.
See public spreadsheet for data: https://docs.google.com/spreadsheets/d/1V7CpCxBH0lg6wi1TAhfZJP5gXE8hj7ivQ8_ULxLSLgs/edit?usp=sharing
I wish to create an array inside a variable. In this array I want all quantity of column "D" but only if column "C" is "Buy".
This is the code I have tried but it comes back empty:
const ss = SpreadsheetApp.getActiveSpreadsheet();
const historySheet = ss.getSheetByName('Blad1');
function quantBuy () {
const searchRange = historySheet.getRange(3,2,historySheet.getLastRow()-1, 2)
let rangeValues = searchRange.getValues();
for (i = 0; i < historySheet.getLastRow()-1; i++) {
if (rangeValues[i] === 'Buy') {
console.log(i);
}}}
Any help is appreciated.
getValues is 2 demiensional
function quantBuy () {
const searchRange = historySheet.getRange(3,3,historySheet.getLastRow()-1, 2)
let rangeValues = searchRange.getValues();
for (let i = 0; i < rangeValues.length; i++) {
if (rangeValues[i][0] === 'Buy') {
console.log(rangeValues[i][1]);
}
}
}

PointCloud Component render issue fetch() custom data [react-three-fiber]

Based on a snippet of original r3f-example found in PointCloud.js
Tested by myself, this above original component is able to render pointcloud by pushing individual x y z value into the for-loop in Particle() function.
I modified it and added a `fetch()' method to retrieve a custom data txt file, snippet as shown below,
...
export function Particles() {
const [positions, colors] = useMemo(() => {
let positions = [], colors = []
positions.length = 3
colors.length = 3
const HEADER_SIZE = 4;
let stream, longArray, len;
let clusterCount ;
let xy_size ;
let clusterSize = [];
let XY_arr = [];
fetch(map)
.then((r) => r.text())
.then(text => {
stream = text.toString().split("\n"); // split by next line
longArray = stream.slice(2,); // remove header from main longArray
len = longArray.length;
for (let i = 0, count = 0; i < len; i += HEADER_SIZE ) {
xy_size = longArray.slice((i + HEADER_SIZE - 1), (i + HEADER_SIZE));
XY_arr.push(longArray.slice((i + HEADER_SIZE ), (i + HEADER_SIZE + xy_size*2)));
console.log(" Points in PointCloud " + count + ": " + xy_size );
clusterSize.push(xy_size);
clusterCount = count;
i += xy_size*2;
count ++;
}
for (let i = 0; i < (clusterCount-2); i++) {
for (let j = 0; j < clusterSize[i]*2; j+=2) {
positions.push( XY_arr[i][j] )
positions.push(0)
positions.push( XY_arr[i][j+1] )
colors.push(1)
colors.push(0.5)
colors.push(0.5)
console.log( XY_arr[i][j] );
}
}
}
)
return [new Float32Array(positions), new Float32Array(colors)]
}, [])
...
...
, map is the custom text file in string, with single data line-by-line
The fetch() method is able to read a custom pointcloud file into XY_arr as an object of Array(). I have checked that XY_arr[i][j] in the nested-forloop are able to return correct x and z value in console.
Current problem is that no pointcloud being rendered onto <Canvas />
Is the problem caused by position.push() nested loop being inside of 'fetch()' method ? And how to resolve. Thank you.
better use const [state, set] = useState() and then fetch in useEffect calling "set" when you're done. putting an async fetch request inside useMemo is practically a side-effect in the render function - which isn't good, nor will it work like that.

Multidimensional Arrays and one of the fields

There is a multi-d array and I want to reach specific field in it. I have look around it but I was unable to find proper answer to my question.
My array is like that;
array-md
columns-- 0 | 1 | 2
index 0 - [1][John][Doe]
index 1 - [2][Sue][Allen]
index 2 - [3][Luiz][Guzman]
.
.
.
index n - [n+1][George][Smith]
My question is how can I reach only second column of the array? I tried name = array[loop][1]; but it says "Cannot access a property or method of a null object reference". What is the right way to do that?
Here is main part of the code.
get
var lpx:int;
var lpxi:int;
var arrLen:int = Info.endPageArray.length;
for(lpx = 0; lpx < arrLen; lpx++)
{
for(lpxi = Info.endPageArray[lpx][2]; lpxi < Info.endPageArray[lpx][1]; lpxi++)
{
if(Info._intervalSearch[lpxi] == "completed")
{
successCount++;
Info._unitIntervalSuccess.push([lpx, successCount / (Info._intervalSearch.length / 100)]);
}
}
}
set
for(lpix = 0; lpix < arrayLength; lpix++)
{
if(lpix + 1 <= arrayLength)
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix + 1], Info._UnitsTriggers[lpix]]);
}
else
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix], Info._UnitsTriggers[lpix - 1]]);
}
}
Try this:
var tempArr:Array = [];
function pushItem(itemName:String, itemSurname:String):void
{
var tempIndex:int = tempArr.length;
tempArr[tempIndex] = {};
tempArr[tempIndex][tempIndex + 1] = {};
tempArr[tempIndex][tempIndex + 1][name] = {};
tempArr[tempIndex][tempIndex + 1][name][itemSurname] = {};
}
function getNameObject(index:int):Object
{
var result:Object;
if(index < tempArr.length)
{
result = tempArr[index][index + 1];
}
return result;
}
pushItem("Max", "Payne");
pushItem("Lara", "Croft");
pushItem("Dart", "Vader");
//
trace(getNameObject(0));
trace(getNameObject(1));
trace(getNameObject(2));
Multidimensional array is an array of arrays, which you can create like this :
var persons:Array = [
['John', 'Doe'],
['Sue', 'Allen'],
['Luiz','Guzman']
];
var list:Array = [];
for(var i:int = 0; i < persons.length; i++)
{
list.push([i + 1, persons[i][0], persons[i][1]]);
}
trace(list);
// gives :
//
// 1, John, Doe
// 2, Sue, Allen
// 3, Luiz, Guzman
Then to get some data :
for(var j:int = 0; j < list.length; j++)
{
trace(list[j][1]); // gives for the 2nd line : Sue
}
For more about multidimensional arrays take a look here.
Hope that can help.

Resources