为什么我的阵列排序不正确?

时间:2018-08-24 23:57:14

标签: javascript arrays sorting

我正在尝试执行以下操作。

首先,输入一个字符串并计算唯一单词的数量。
其次,按降序对唯一字数进行排序。
第三,如果两个单词的单词数相同,则将它们按出现的顺序放置。

问题:为什么单词“ up”首先出现在我返回的数组数组中?

var doc = 
"Cause I'm Slim Shady, yes I'm the real Shady, All you other Slim Shadys are just imitating So won't the real Slim Shady, please stand up, Please stand up, Please stand up";

function wordCountEngine(doc) {
    var stringModArr = doc.replace(/[.,'\/#!$%\^&\*;:{}=\-_`~?()]/g, "").toLowerCase().split(" ");
    var wordLibrary = {};

    for (let i = 0; i < stringModArr.length; i++) {
        if (wordLibrary.hasOwnProperty(stringModArr[i])) {
            wordLibrary[stringModArr[i]] = String((Number(wordLibrary[stringModArr[i]])) + 1);
        } else {
            wordLibrary[stringModArr[i]] = '1';
        }
    }

    var sortable = [];
    for (var word in wordLibrary) {
        sortable.push([word, wordLibrary[word]]);
    }

    var final = sortable.sort(function(a, b) {
        return b[1] - a[1];
    });

    return final;
}

wordCountEngine(doc)

4 个答案:

答案 0 :(得分:2)

用于排序功能的排序算法无法确保原始顺序。如果将日志放在compareFunction中,则可以调试它。如果需要命令,那么在编写代码时必须考虑到这一点。下面的代码可能会有所帮助。

var doc = “因为我是Slim Shady,是的,我才是真正的Shady,其他所有Slim Shadys都在模仿,所以不是真正的Slim Shady,请站起来,请站起来,请站起来”;

   function wordCountEngine(doc) {
     var stringModArr = doc.replace(/[.,'\/#!$%\^&\*;:{}=\-_`~?()]/g, 
      "").toLowerCase().split(" ");
var wordLibrary = {};

for (let i = 0; i < stringModArr.length; i++) {
    if (wordLibrary.hasOwnProperty(stringModArr[i])) {
        wordLibrary[stringModArr[i]] = String((Number(wordLibrary[stringModArr[i]])) + 1);
    } else {
        wordLibrary[stringModArr[i]] = '1';
    }
}

var sortable = [];
let i = 0;
for (var word in wordLibrary) {
    sortable.push([i, word, wordLibrary[word]]);
    i++;
}
var final = sortable.sort(function(a, b) {
    if(b[2] - a[2] != 0) {
      return b[2] - a[2];
    } else {
      return a[0] - b[0];
    }
});

return final.map(a => [a[1], a[2]]);
  }

  wordCountEngine(doc)

答案 1 :(得分:1)

首先显示“向上”,因为您的函数是根据“计数”的降序进行排序的。

> wordCountEngine(doc)
[ [ 'up', '3' ],
  [ 'slim', '3' ],
  [ 'shady', '3' ],
  [ 'please', '3' ],
  [ 'stand', '3' ],
  [ 'the', '2' ],
  [ 'real', '2' ],
  [ 'im', '2' ],
  [ 'you', '1' ],
  [ 'cause', '1' ],
  [ 'shadys', '1' ],
  [ 'are', '1' ],
  [ 'just', '1' ],
  [ 'imitating', '1' ],
  [ 'so', '1' ],
  [ 'wont', '1' ],
  [ 'yes', '1' ],
  [ 'all', '1' ],
  [ 'other', '1' ] ]

如果您想按字母顺序对单词进行排序,请在调用sort时使用0索引而不是1。

答案 2 :(得分:1)

您按顺序推送它们,但是对它们进行排序时,出现的顺序就会丢失。

为了找回它,您需要根据事件的发生对其加权。可以通过切片来创建一个新的数组来使用,然后在比较中考虑它们的先前顺序来完成此操作。

var final = sortable.slice().sort(function(a, b) {
  var occurenceWeightA = (sortable.length - sortable.indexOf(a)) / sortable.length;
  var occurenceWeightB = (sortable.length - sortable.indexOf(b)) / sortable.length;
  return (occurenceWeightB + (+b[1])) - (occurenceWeightA + (+a[1]));
});

jsFiddle Demo

使用(+b[1])是为了确保存在整数数学而不是字符串连接。 +是转换为数字的简写。

答案 3 :(得分:0)

这是一种略有不同的方法,该方法将wordLibraryfirstIndex作为单词关键字的值添加到对象中,该对象跟踪句子中出现的lastIndexvar doc = "Cause I'm Slim Shady, yes I'm the real Shady, All you other Slim Shadys are just imitating So won't the real Slim Shady, please stand up, Please stand up, Please stand up"; function wordCountEngine(doc) { var stringModArr = doc.replace(/[.,'\/#!$%\^&\*;:{}=\-_`~?()]/g, "").toLowerCase().split(" "); var wordLibrary = {}; for (let i = 0; i < stringModArr.length; i++) { var key = stringModArr[i], obj = {first: stringModArr.indexOf(key),last: stringModArr.lastIndexOf(key)} wordLibrary[key] = Object.assign(obj, { count: wordLibrary[key] ? Number(wordLibrary[key].count || 1) + 1 : 1 }) } var sortable = []; for (var word in wordLibrary) { sortable.push([word, wordLibrary[word]]); } var final = sortable.sort(function(a, b) { return b[1].count - a[1].count === 0 ? a[1].first - b[1].first : b[1].count - a[1].count }); return final; } console.log(wordCountEngine(doc))单词以及像以前一样计数。

这使您可以更好地跟踪和以后进行排序,现在您已经有了元数据:

    import UIKit
var aa:[NSLayoutConstraint] = []
class ViewController: UIViewController {

var btn : UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    btn = UITextField(frame: CGRect(x: 50, y: 100, width: 200, height: 50))

    let leadingc2 = btn.widthAnchor.constraint(equalToConstant: 80)
    let trailingC2 = btn.heightAnchor.constraint(equalToConstant: 50)
    let topc2 = btn.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -50)
    let bottomc2 = btn.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

    aa = [leadingc2,trailingC2,topc2,bottomc2]

    NSLayoutConstraint.activate(aa)
    self.view.addSubview(btn)
}


}

所以它的工作方式是,如果您的单词具有相同的计数,现在您可以将其与第一次出现的单词进行比较等等。

您可以将其缩短很多,但我想保留大部分结构,以便让您有宾至如归的感觉。希望这会有所帮助。