随机排列数组中的键

时间:2019-01-26 00:35:22

标签: javascript

我有一个数组

var array = [{
  "Abigail": ["I feel that anyone breaking the law deserves what they get", "1"],
  "Alexandra": ["There comes a time that you can just", "5"],
  "Alexis": ["She looks mean anyways.", "2"]
}, {
  "Abigail": ["Bet she wishes she hadn't broken the law", "1"],
  "Alexandra": ["Bad girls don't wear scarfs.", "5"],
  "Alexis": ["That's the look of someone who has lost hope in humanity.", "5"]
}, {
  "Abigail": ["She probably wanted this to happen.", "1"],
  "Alexandra": ["What did she do to warrent all of this attention?", "5"],
  "Alexis": ["I think people just going about it all wrong.", "5"]
}]

我只想对数组中的名称进行混洗,但希望保持名称的顺序相同。

我尝试了很多事情,包括Fisher-Yates Shuffle https://bost.ocks.org/mike/shuffle/的代码。我只能在较低级别的列表中随机播放,而不能在名称中随机播放。

期望结果的示例:

var arrayShuffled = [{
  "Abigail": ["I feel that anyone breaking the law deserves what they get", "1"],
  "Alexis": ["She looks mean anyways.", "2"],
  "Alexandra": ["There comes a time that you can just stop screaming in peoples ears.", "5"]
}, {
  "Abigail": ["Bet she wishes she hadn't broken the law", "1"],
  "Alexis": ["That's the look of someone who has lost hope in humanity.", "5"],
  "Alexandra": ["Bad girls don't wear scarfs.", "5"]
}, {
  "Abigail": ["She probably wanted this to happen.", "1"],
  "Alexis": ["I think people just going about it all wrong.", "5"],
  "Alexandra": ["What did she do to warrent all of this attention?", "5"]
}]

3 个答案:

答案 0 :(得分:1)

首先将其中一行的键随机化,然后使用这些键重新创建所有行:

var a = [{
  "Abigail": ["I feel that anyone breaking the law deserves what they get", "1"],
  "Alexandra": ["There comes a time that you can just", "5"],
  "Alexis": ["She looks mean anyways.", "2"]
}, {
  "Abigail": ["Bet she wishes she hadn't broken the law", "1"],
  "Alexandra": ["Bad girls don't wear scarfs.", "5"],
  "Alexis": ["That's the look of someone who has lost hope in humanity.", "5"]
}, {
  "Abigail": ["She probably wanted this to happen.", "1"],
  "Alexandra": ["What did she do to warrent all of this attention?", "5"],
  "Alexis": ["I think people just going about it all wrong.", "5"]
}]

var keys = Object.keys(a[0]);
keys.sort(function(a, b) {
  return Math.random() - 0.5;
});

var a_shuffled = [];
for (var i = 0; i < a.length; i++) {
  a_shuffled[i] = {}
  keys.forEach(function(k) {
    a_shuffled[i][k] = a[i][k]
  });
}
console.log(a_shuffled);
.as-console-wrapper { top: 0; max-height: 100% !important; }

答案 1 :(得分:1)

与Laurens的区别不大,但它在键上实现了Knuth(或Fisher-Yates)随机播放。我还使用了ES6语法。

var objList = [{
  "Abigail": ["I feel that anyone breaking the law deserves what they get", "1"],
  "Alexandra": ["There comes a time that you can just", "5"],
  "Alexis": ["She looks mean anyways.", "2"]
}, {
  "Abigail": ["Bet she wishes she hadn't broken the law", "1"],
  "Alexandra": ["Bad girls don't wear scarfs.", "5"],
  "Alexis": ["That's the look of someone who has lost hope in humanity.", "5"]
}, {
  "Abigail": ["She probably wanted this to happen.", "1"],
  "Alexandra": ["What did she do to warrent all of this attention?", "5"],
  "Alexis": ["I think people just going about it all wrong.", "5"]
}]

console.log(shuffleArrayItemKeys(objList)) // Print the shuffled list.

function shuffleArrayItemKeys(arr) {
  var keys = knuthShuffle(Object.keys(arr[0]))
  return arr.map((item) => {
    return keys.reduce((result, key, index) => {
      return { ... result, ... { [key] : item[key] } }
    }, {})
  })
}

function knuthShuffle(arr) {
  var currIndex = arr.length, randIndex
  while (currIndex !== 0) {
    randIndex = Math.floor(Math.random() * currIndex)
    currIndex--
    __swap__(arr, currIndex, randIndex)
  }
  return arr
}

/**
 * @private
 */
function __swap__(arr, index1, index2) {
  let tmp = arr[index1]
  arr[index1] = arr[index2]
  arr[index2] = tmp
}
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}

注意:可以使用Object.assign(result, { [key] : item[key] })代替点差运算符,例如{ ... result, ... { [key] : item[key] } }作为浏览器更友好的选择。

答案 2 :(得分:0)

JavaScript中的对象的条目没有特别定义的顺序。如果我要创建一个看起来像[1,3,5,7,9] array ,则这些元素不是按其键排序的,而是按其值排序的。该数组相当于定义一个对象

let arr = [1,3,5,7,9];
let obj = {
    0: 1, 
    1: 3, 
    2: 5,
    3: 7,
    4: 9
};

两者之间的区别在于Array是一个Object,但Object不是Array。

arr instanceof Object //true
arr instanceof Array  //true
obj instanceof Object //true
obj instanceof Array  //false

由于键是JavaScript中的自然顺序,因此您无法混洗对象的实际元素。如果我要改组该数组,则键不会更改顺序,而只是更改与每个键关联的值。

如果您想实现自己的目标,则需要重组数据。您需要做的是创建

var array = [
    [
        {"Abigail":["...", "1"]},
        {"Alexandra": ["...", "5"]},
        {"Alexis": ["...", "2"]}
    ], [//...
    ]
];

现在像这样定义,它们存在于数组中,因此可以将它们改组-您只需要更改访问事物的方式,因为它们现在是由索引而不是已定义的键绑定的。