Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering array by index and matching values

I'm tying to filter out a pattern for a slot machine, in this case I want the following indexes to be selected if they have the same value.

If indexes 0, 2 and 6 has the same value if should be outputted. I was thinking something like a function call maybe like this

if (win_filter([0, 2, 6] == "slot-2") {
    console.log("You won");
}

My code is the following below.

var final_score = new Array();

$(".shoot").click(function() {

  //var numbers_array = ["slot-1", "slot-1", "slot-1", "slot-1", "slot-1", "slot-2", "slot-2", "slot-2", "slot-2", "slot-3", "slot-3", "slot-3", "slot-4", "slot-4", "slot-5"];
  var numbers_array = ["slot-1", "slot-2", "slot-3", "slot-4", "slot-5"];
  var target = $("div.window table");

  target.find("tr td > div").each(function() {
    $(this).fadeOut(function() {
      $(this).removeAttr('class');
      $(this).addClass(numbers_array[Math.floor(Math.random() * numbers_array.length)]);
      $(this).fadeIn();
      final_score.push($(this).attr("class"));
    });
  });

  function filterResults(arr) {
    return final_score.filter(function(el) {
      return arr.some(function(e) {
        return el.timeframe == e;
      });
    });
  }

  var result = filterResults(['0','2','6']);
  console.log(result);

  $.each(numbers_array, function(index, value) {
    if (result == value) {
      $(".notice").html("You have won.").addClass("success").show();
      console.log("You won!");
    }
  });
  console.log(final_score);
});

Edit

If it wasn't clear I meant the indexes in the array, in case if I picked the indexes 0, 2 and 6 from this generated array the value of those would be (even if they aren't the same).

0 => "slot-2", 2 => "slot-5", 6 => "slot-1"

The goal is to check if the selected indexes has the same value output. And the amount of indexes shouldn't be hardcoded, it can be anything from 3 index searches to 5 index searches.

jsFiddle.net

Array[0]
0 : "slot-2"
1 : "slot-3"
2 : "slot-5"
3 : "slot-5"
4 : "slot-4"
5 : "slot-3"
6 : "slot-1"
7 : "slot-4"
8 : "slot-1"
9 : "slot-2"
10 : "slot-2"
11 : "slot-4"
12 : "slot-5"
13 : "slot-1"
14 : "slot-4"
like image 469
Tweath Avatar asked Jan 09 '17 14:01

Tweath


People also ask

How can we filter an array of elements from a given array in ES6?

ES6 | Array filter() Method Callback: The function is a predicate, to test each element of the array. Return true to keep the element, false otherwise. It accepts three arguments: element: The current element being processed in the array.

How do you use an array filter?

The filter() method creates a new array filled with elements that pass a test provided by a function. The filter() method does not execute the function for empty elements. The filter() method does not change the original array.


2 Answers

First of all, I avoided to make any major modifications to your code, so in the jsfiddle I wrote the validation exactly where you were expecting it (inside the on('click')).

What I did:

Previous to calculating anything, we need the slots data. You were already saving it inside final_score, but the function which was doing so was a callback. Is it worth it waiting for the callback? - I do not think so, because it is a simple css (fadeOut) animation.

const classVal = numbers_array[Math.floor(Math.random() * numbers_array.length)];
$(this.fadeOut(function() { // Rest of your code }
final_score.push(classVal);

Calculate the length of each row, you know that they will all be equal length and you have all of them inside an array (final_score), so a simple division by the number of lines is enough.

const lines = 3;
const lineLength = final_score.length/lines;

For each line we check whether the other line values are the same as this one. Given that your array order is not based on the display order but rather on the order you generated them, we can simply check the ones with the same index (but iterating over each line).

final_score[i] === final_score[i+lineLength] && final_score[i] === final_score[i+lineLength*2]

Resulting in:

  const lineLength = final_score.length/3;
  for(let i=0; i<lineLength; i++) {
    if (final_score[i] === final_score[i+lineLength] && final_score[i] === final_score[i+lineLength*2]) {
      console.info(`win col ${i}`);
    }
  }

If you need it, you can easily n-ify this.

  const lineLength = final_score.length/3;
  for(let i=0; i<lineLength; i++) {
    const lineOneSlot = final_score[i];
    let allEqual = true;
    for (let j=1; j<lines; j++) {
        console.info(`Comparing ${i} ${i+lineLength*j}`);
        if (lineOneSlot !== final_score[i+lineLength*j]) {
        allEqual = false;
        break;
      }
    }
    if (allEqual) {
      console.info(`win col ${i}`);
    }
  }

Since you asked for a diagonal check as well, it would look like this:

However, you have to make sure that the grid is a square to get your expected results. Otherwise, you would have to redefine what exactly to do in these cases.

final_score[i] === final_score[i+1+lineLength] && final_score[i] === final_score[i+line+lineLength*line]

https://jsfiddle.net/qjp7g0qL/3/

like image 150
zurfyx Avatar answered Oct 14 '22 18:10

zurfyx


Reading through your breifing and comments, get the idea that you are trying to create some slot machine, where the center row is used for the matching evaluation. Hence changed a few lines in your code to get it done. JS FIDDLE DEMO

NOTE: I have tried two approach, for a WINNER state.
1. All items of CENTER ROW should be the same.
2. All items of CENTER ROW should be laid out in the same as the PATTERN
FYI: COMMENTED LINE 21 in JS for easy testing ...

/* checks if selected items are matching the winning pattern ... */
function areItemsMatchingWinningPattern(selectedItems, winningItemsPattern) {
  return !!selectedItems && !!winningItemsPattern && (selectedItems.length == winningItemsPattern.length) && selectedItems.every(function (elm, idx) { 
    return elm === winningItemsPattern[idx]; 
  })
}

/* checks if all selected items are same ....  */
function areAllItemsMatching(source) {
  return !!source && source.length > 0 && source.every(function (elm, idx, array) { 
    return idx === 0 || array[idx - 1] == elm; 
  });
}
like image 34
Thirueswaran Rajagopalan Avatar answered Oct 14 '22 17:10

Thirueswaran Rajagopalan