根据索引和匹配值过滤数组

时间:2022-09-25 07:58:07

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

如果索引0、2和6的值相同,则应该输出。我在想一个函数调用可能是这样的。

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,2和6,那么它们的值将是(即使它们不相同)。

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.

目标是检查所选索引是否具有相同的值输出。而且索引的数量不应该硬编码,可以是3个索引搜索到5个索引搜索。

jsFiddle.net

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"

5 个解决方案

#1


1  

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')).

首先,我避免对您的代码进行任何重大修改,所以在jsfiddle中,我将验证准确地写到您期望的地方(在on中(“单击”)。

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.

在计算任何东西之前,我们都需要插槽数据。你已经在final_score中保存了它,但是这个函数是一个回调函数。等待回调是否值得?-我不这么认为,因为这是一个简单的css (fadeOut)动画。

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.

计算每一行的长度,您知道它们的长度都是相等的,并且在一个数组中都有它们(final_score),所以用行数进行简单的除法就足够了。

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]

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.

如果你需要它,你可以很容易地把它n-ify (n-ify)。

  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]

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

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

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

#2


1  

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

通读你的简要说明和评论,得到这样的想法:您正在尝试创建一个*,中心行用于匹配评估。因此,在代码中更改了几行代码以完成它。JS小提琴演示

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 ...

注:我尝试了两种方法,一种获胜的状态。1。中心行中的所有项都应该是相同的。2。中心行的所有项目都应该按照如下模式进行布局:在JS中注释第21行,便于测试……

/* 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; 
  });
}

#3


0  

This scheme could check for winning conditions given a non-empty arbitrary length list of valid indexes. Here is the working JSFiddle.

该方案可以检查给定有效索引的非空任意长度列表的获胜条件。这是工作的JSFiddle。

var win_filter = function(indexes, allValues) {
    // assumes all indexes are valid

    // gather all the values from the slot machine by index.
    var values = [];
    for (var i = 0; i < indexes.length; i++)
        values.push(allValues[indexes[i]]);

    // if every value matches the others, then all values match the first
    if (values.every(function(x) { return x == values[0]; }))
        return values[0];  // return the value that was the same

    // No match found, return null to signify that no winning condition was found.
    return null;
}

$(".shoot").on('click', function() {
    var final_score = [];
    var numbers_array = ["slot-1", "slot-2", "slot-3", "slot-4", "slot-5"];

    // ...

    // Instead of iterating through the possible winning values, if there was any match, it means they won, and winningMatch will contain that matching value. ie 'slot-1'
    var winningMatch = win_filter([0, 2, 6], final_score);
    if (winningMatch) {
        $(".notice").html("You have won.").addClass("success").show();
    }
});

Note that if any matching set of any available class name wins, then we don't have to iterate through the list of possible winning cases to determine that the game was won, because wouldn't any match win?

注意,如果任何可用的类名的匹配集都获胜,那么我们就不需要遍历可能获胜的案例的列表,以确定游戏是否赢了,因为没有任何一场比赛获胜?

#4


0  

You asked for a comparison function, here it is:

你要求一个比较函数,这里是:

function compareMultiple(sourceArray, indexesArray, compareToValue){ 

    for (let i = 0; i < indexesArray.length; i++){ 

        let index = indexesArray[i]

        if (!sourceArray[index] || sourceArray[index] !== compareToValue) {
            return false
        }
    } 

    return true
}

It accept three arguments: array of values, array of indexes to pick items and value to match the condition. Function returns a true / false. You can call it this way:

它接受三个参数:值数组、选择项的索引数组和匹配条件的值。函数返回true / false。你可以这样称呼它:

let isWin = compareMultiple(
    ['slot-1','slot-2','slot-1','slot-3','slot-4', 'slot-2', 'slot-1'], 
    [0, 2, 6], 
    'slot-1'
)

console.log(isWin); // true

Here is an example (i reduced number_array to increase a chance to win and rewrite a little bit of code just for demonstration). In this example i also used promises to wait until jquery fadeOut animation will be completed and we can check if new combination of slots is win (since you put new values in a final_score only on fadeOut complete asynchronous callback but check it right after the $.each your fiddle wont work as expected).

这里有一个例子(我减少了number_array以增加一个获胜的机会,并为演示重写了一些代码)。在本例中,我还使用了诺言,等待jquery fadeOut动画完成,我们可以检查新的插槽组合是否为win(因为您只在fadeOut的完整异步回调上添加新值,但是在$之后检查它。你的小提琴不能按预期的那样工作。

#5


0  

Fiddle: https://jsfiddle.net/q3eh0n9f/4/

小提琴:https://jsfiddle.net/q3eh0n9f/4/

var options = [
    "slot-2",
    "slot-3",
    "slot-5",
    "slot-5",
    "slot-4",
    "slot-3",
    "slot-1",
    "slot-4",
    "slot-1",
    "slot-2",
    "slot-2",
    "slot-4",
    "slot-5",
    "slot-1",
    "slot-4"
];

// convert selections to usable values and filter unique elements
function buildResults (arr) {
    return arr.map(function (index) {
        return options[index];
    }).filter(function (value, i, arr) {
        return arr.indexOf(value) === i;
    });
}

// if array has been reduced to the length of 1 it is a winner
function checkResults (results) {
    if (results.length === 1) return true;
    if (results.length !== 1) return false;
}

var result = checkResults(buildResults([0, 2, 3]));

console.log(result); // false

#1


1  

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')).

首先,我避免对您的代码进行任何重大修改,所以在jsfiddle中,我将验证准确地写到您期望的地方(在on中(“单击”)。

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.

在计算任何东西之前,我们都需要插槽数据。你已经在final_score中保存了它,但是这个函数是一个回调函数。等待回调是否值得?-我不这么认为,因为这是一个简单的css (fadeOut)动画。

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.

计算每一行的长度,您知道它们的长度都是相等的,并且在一个数组中都有它们(final_score),所以用行数进行简单的除法就足够了。

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]

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.

如果你需要它,你可以很容易地把它n-ify (n-ify)。

  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]

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

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

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

#2


1  

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

通读你的简要说明和评论,得到这样的想法:您正在尝试创建一个*,中心行用于匹配评估。因此,在代码中更改了几行代码以完成它。JS小提琴演示

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 ...

注:我尝试了两种方法,一种获胜的状态。1。中心行中的所有项都应该是相同的。2。中心行的所有项目都应该按照如下模式进行布局:在JS中注释第21行,便于测试……

/* 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; 
  });
}

#3


0  

This scheme could check for winning conditions given a non-empty arbitrary length list of valid indexes. Here is the working JSFiddle.

该方案可以检查给定有效索引的非空任意长度列表的获胜条件。这是工作的JSFiddle。

var win_filter = function(indexes, allValues) {
    // assumes all indexes are valid

    // gather all the values from the slot machine by index.
    var values = [];
    for (var i = 0; i < indexes.length; i++)
        values.push(allValues[indexes[i]]);

    // if every value matches the others, then all values match the first
    if (values.every(function(x) { return x == values[0]; }))
        return values[0];  // return the value that was the same

    // No match found, return null to signify that no winning condition was found.
    return null;
}

$(".shoot").on('click', function() {
    var final_score = [];
    var numbers_array = ["slot-1", "slot-2", "slot-3", "slot-4", "slot-5"];

    // ...

    // Instead of iterating through the possible winning values, if there was any match, it means they won, and winningMatch will contain that matching value. ie 'slot-1'
    var winningMatch = win_filter([0, 2, 6], final_score);
    if (winningMatch) {
        $(".notice").html("You have won.").addClass("success").show();
    }
});

Note that if any matching set of any available class name wins, then we don't have to iterate through the list of possible winning cases to determine that the game was won, because wouldn't any match win?

注意,如果任何可用的类名的匹配集都获胜,那么我们就不需要遍历可能获胜的案例的列表,以确定游戏是否赢了,因为没有任何一场比赛获胜?

#4


0  

You asked for a comparison function, here it is:

你要求一个比较函数,这里是:

function compareMultiple(sourceArray, indexesArray, compareToValue){ 

    for (let i = 0; i < indexesArray.length; i++){ 

        let index = indexesArray[i]

        if (!sourceArray[index] || sourceArray[index] !== compareToValue) {
            return false
        }
    } 

    return true
}

It accept three arguments: array of values, array of indexes to pick items and value to match the condition. Function returns a true / false. You can call it this way:

它接受三个参数:值数组、选择项的索引数组和匹配条件的值。函数返回true / false。你可以这样称呼它:

let isWin = compareMultiple(
    ['slot-1','slot-2','slot-1','slot-3','slot-4', 'slot-2', 'slot-1'], 
    [0, 2, 6], 
    'slot-1'
)

console.log(isWin); // true

Here is an example (i reduced number_array to increase a chance to win and rewrite a little bit of code just for demonstration). In this example i also used promises to wait until jquery fadeOut animation will be completed and we can check if new combination of slots is win (since you put new values in a final_score only on fadeOut complete asynchronous callback but check it right after the $.each your fiddle wont work as expected).

这里有一个例子(我减少了number_array以增加一个获胜的机会,并为演示重写了一些代码)。在本例中,我还使用了诺言,等待jquery fadeOut动画完成,我们可以检查新的插槽组合是否为win(因为您只在fadeOut的完整异步回调上添加新值,但是在$之后检查它。你的小提琴不能按预期的那样工作。

#5


0  

Fiddle: https://jsfiddle.net/q3eh0n9f/4/

小提琴:https://jsfiddle.net/q3eh0n9f/4/

var options = [
    "slot-2",
    "slot-3",
    "slot-5",
    "slot-5",
    "slot-4",
    "slot-3",
    "slot-1",
    "slot-4",
    "slot-1",
    "slot-2",
    "slot-2",
    "slot-4",
    "slot-5",
    "slot-1",
    "slot-4"
];

// convert selections to usable values and filter unique elements
function buildResults (arr) {
    return arr.map(function (index) {
        return options[index];
    }).filter(function (value, i, arr) {
        return arr.indexOf(value) === i;
    });
}

// if array has been reduced to the length of 1 it is a winner
function checkResults (results) {
    if (results.length === 1) return true;
    if (results.length !== 1) return false;
}

var result = checkResults(buildResults([0, 2, 3]));

console.log(result); // false