【问题标题】:Renaming duplicates in Javascript Array重命名 Javascript 数组中的重复项
【发布时间】:2012-05-25 12:21:06
【问题描述】:

如果变量已存在于字符串中,我正在寻找重命名(追加 1、-2 等)变量的最有效方法。

所以我保留了一个数组"

dupeCheck = [];

当我看到一个变量时:

var UID;

已经在我的 dupeCheck 数组中,我想立即将 UID 的值附加 -1,

另外,我需要防止第三个重复成为 string-1-1,而是 string-2..

我之前看过这个:Appending the count to duplicates in a javascript string array,但这不是我想要的……

有什么聪明的主意吗?我更喜欢 jQuery..

/编辑:

例如:

var dupeUIDCheck = [];  

$.each(data[IDS].UIDs[keys], function(keys, val)
     {
     var currString = val;
     switch (key)
 {
      case "UID":

       UID = unquote(currString);

   //TODO:
   //Detect if multiple UIDs are loaded from a single source, and
   //rename them:

   dupeUIDCheck.push(UID); //Push current ID onto existing array

       //Check if ID exists
       ?
       //If exists rename value of currString, save it in currString
       newName = currSting;
      break;

      case "otherstuff":
           //Other vars to parse
      break;
     }

所以当我们摆脱“UID”的情况时,我想确保它具有唯一值

【问题讨论】:

  • 您能更详细地描述一下这些步骤吗? UID 是您拥有多少重复项的计数,还是您要针对dupeCheck 的值检查的var 值?我不知道你想做什么。

标签: jquery arrays duplicates


【解决方案1】:

您可以将功能包装在一个函数中以便能够重用它。下面的函数接受一个字符串列表并返回-1-2等后缀的字符串列表。

function suffixDuplicates( list )
{
    // Containers

    var count = { };
    var firstOccurences = { };

    // Loop through the list

    var item, itemCount;
    for( var i = 0, c = list.length; i < c; i ++ )
    {
        item = list[ i ];
        itemCount = count[ item ];
        itemCount = count[ item ] = ( itemCount == null ? 1 : itemCount + 1 );

        if( itemCount == 2 )
            list[ firstOccurences[ item ] ] = list[ firstOccurences[ item ] ] + "-1";
        if( count[ item ] > 1 )
            list[ i ] = list[ i ] + "-" + count[ item ]
        else
            firstOccurences[ item ] = i;       
    }

    // Return
    return list;
}

例如,输入

[ "Barry", "Henk", "Jaap", "Peter", "Jaap", "Jaap", "Peter", "Henk", "Adam" ]

返回输出

[ "Barry", "Henk-1", "Jaap-1", "Peter-1", "Jaap-2", "Jaap-3", "Peter-2", "Henk-2", "Adam" ]

要查看它的实际效果,here 是一个指向 jsFiddle 示例的链接。

【讨论】:

  • 这是我想要的,但是,我不想返回一个列表/数组,而只是重命名的值,所以列表/数组只是为了跟踪欺骗
【解决方案2】:

您的问题有点难以理解,但如果您指的是这个,请告诉我。假设我们有一串单词,其中一些单词重复。我们想用一个新的后缀来修改那些重复的单词,例如-1-2,这取决于它是哪个实例。

// Start by creating our string, word array, and result array
var string = "one two one one two one three three one three",
    values = string.split(" "), result = [];

// For every word in the values array
for ( var i = 0; i < values.length; i++ ) {

  // Set a word variable, and an integer suffix
  var word = values[i], int = 1;

  // While our current word (with/without suffix) exists in results
  while ( strArr(word, result) >= 0 ) 
    // Increment the suffix on our word
    word = values[i] + "-" + int++;

  // Push word into result array
  result.push(word);
}

// Function for determining if a string is in an array
function strArr(s,a){
  for ( var j = 0; j < a.length; j++ )
    if ( a[ j ] == s ) return j;
  return -1;
}

// Compare the before and after
console.log( string );
console.log( result.join(" ") );

我们的结果是

one two one one two one three three one three
one two one-1 one-2 two-1 one-3 three three-1 one-4 three-2

【讨论】:

  • 一个非常好的明确答案,我实际上通过在数组上使用 .includes() 检查切换您的 strArr 函数来稍微优化了这一点。我相信你可以轻松地走得更远。
【解决方案3】:

保留您正在检查的重复项的列表的最佳方法是将它们放在一个对象中,而不是一个数组中,这样您就可以快速查找它们,然后生成一个尚未使用的唯一后缀每一次。此函数允许您将 id 传递给函数并让函数返回该 id 的唯一版本,该版本尚未使用。如果传入的内容没有被使用,它只会返回它。如果传入的内容正在使用中,它会删除任何后缀并生成一个尚未使用的新后缀并返回新生成的 id。然后将新生成的 id 存储在数据结构中,这样以后也不会重复。

var idList = {};

makeIdUnique(id) {
    if (id in idList) {
        // remove any existing suffix
        var base = id.replace(/-\d+$/, "");
        // generate a new suffix
        var cnt = idList[base] || 1;
        // while new suffix is in the list, keep making a different suffix
        do {
            id = base + "-" + cnt++;
        } while (id in idList);
        // save cnt for more efficient generation next time
        idList[base] = cnt;
    }
    // put the final id in the list so it won't get used again in the future
    idList[id] = true;
    // return the newly generated unique id
    return(id);
}

【讨论】:

  • 这并没有真正做到,stackoverflow.com/questions/10962412/…,并且,修改它仍然留下欺骗:jsfiddle.net/HB7ev/13
  • @TrySpace - 你取出了这一行var base = id.replace(/-\d+$/, "");,这是我算法的重要组成部分,因为它删除了传入的后缀以获取根,因此它可以使用该根创建一个唯一的 cnt。
  • @TrySpace - 你改变了代码并改变了它的行为。例如,您将dupeUIDCheck 放入一个数组,而我将idList 作为一个对象。我也不明白您认为在您的示例中不起作用的内容。也许你需要重申你的目标。而且,当您在响应之间等待数周时,要使上下文保持最新状态有点困难。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 2021-04-17
  • 2013-07-31
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
相关资源
最近更新 更多