2016-06-30 4 views
1

Итак, у меня есть массив объектов. На самом деле объекты следуют спецификации GeoJSON, поэтому имейте это в виду. В объектах «свойства» существует доверенность «имени». Это имя будет A, B, C ... blah ... Z, AA, AB и т. Д. И т. Д. Для каждой отдельной функции. Смотрите пример JSON (я вырезать некоторые другие вещи, которые не были важны для этого вопроса, например, геометрии, а что нет ...):Javascript - Получить следующую букву из массива объектов

{ 
    "features" : [{ 
      "properties" : { 
       "name" : "A", 
       "description" : null, 
      }, 
      "type" : "Feature" 
     }, { 
      "properties" : { 
       "name" : "B", 
       "description" : null, 
      }, 
      "type" : "Feature" 
     }, { 
      "properties" : { 
       "name" : "C", 
       "description" : null, 
      }, 
      "type" : "Feature" 
     } 
    ], 
    "type" : "FeatureCollection" 
} 

То, что я хотел бы сделать, это найти MAX письмо внутри этого массива функций, чтобы возвратить следующий в серии. В этом примере «C» будет считаться MAX, поэтому мне нужно будет вернуть значение «D». Если бы у меня был АА, это считалось бы МАКСЫМ, и оно вернуло бы «АВ». Если максимальное значение оказалось «Z», я хотел бы вернуть значение «AA».
Может игнорировать использование строчных букв и использовать только 26 английских букв верхнего уровня. Никаких других персонажей.

Я считаю, что смогу решить эту проблему с использованием javascript CharCodeAt (index), а также с применением Math.max, добавив + 1, а затем вернемся к описанию символа ascii ... но у меня возникают проблемы с приведением это вместе в рабочей функции, которая охватывает все это.

Помощь будет оценена!

Обновление: Я получил его частично, работая со следующим кодом. Однако не совсем поняли, как заставить его работать, если он обертывается от Z до AA. Или если MAX окажется AF, тогда возвращается AG. AZ должен был вернуть BA.

String.fromCharCode(Math.max.apply(Math,someObject.features.map(function(o){return o.properties.name.charCodeAt(0);})) + 1) 

Другие известные правила:

  • Верхний предел может быть ZZ - весьма маловероятно, что я должен обернуть обратно AAA
  • Максимальный характер не всегда будет последним в массиве, так не может просто получить последнюю функцию массива.
+0

Будет ли MAX всегда просто быть последним объектом в массиве функций? – Ju66ernaut

+0

Не обязательно ... так что вы не могли просто зацепить последний элемент массива – dvsoukup

+0

* считалось бы MAX * - будет MAX произвольным параметром ввода? – RomanPerekhrest

ответ

1

Решение с использованием Array.sort, String.fromCharCode и String.charCodeAt функции:

var someObject = { 
    "features" : [{ 
      "properties" : { "name" : "AB", "description" : null}, 
      "type" : "Feature" 
     }, { 
      "properties" : {"name" : "B", "description" : null}, 
      "type" : "Feature" 
     }, { 
      "properties" : { "name" : "AF", "description" : null}, 
      "type" : "Feature" 
     } 
    ], 
    "type" : "FeatureCollection" 
}; 

function getNext(data) { 
    data.features.sort(function(a,b){ 
     return a.properties.name.length - b.properties.name.length || 
       a.properties.name.localeCompare(b.properties.name); 
    }); 

    var last = data.features[data.features.length - 1].properties.name; 
    if (last.length === 1) { 
     return (last === "Z")? "AA" : String.fromCharCode(last.charCodeAt(0) + 1); 
    } else { 
     if (last === "ZZ") return last; // considering 'ZZ' as a limit 
     if (last[1] !== "Z") { 
      return last[0] + String.fromCharCode(last[1].charCodeAt(0) + 1); 
     } else if (last[1] === "Z"){ 
      return String.fromCharCode(last[0].charCodeAt(0) + 1) + "A"; 
     } 
    }  
} 

console.log(getNext(someObject)); // 'AG' 
+0

Спасибо! Я выбрал этот, поскольку он работает для моих нужд. Я уверен, что некоторые из других ответов работают, но в тот момент это казалось лучше всего. Однако есть одна крошечная проблема с этим в этой строке, чтобы сделать возврат ... поэтому нет необходимости иметь «следующую» переменную: (last === «Z»)? «AA»: String.fromCharCode (last.charCodeAt (0) + 1); Не могли бы вы обновить свой ответ, чтобы это отразить? В противном случае он вернет неопределенный. – dvsoukup

+0

@ dvsoukup, вы были правы. Я исправил это. Проверьте это. благодаря – RomanPerekhrest

0

Вы можете найти строку MAX с:

var maxName = null, 
    obj = null, 
    name = null; 
for(var idx = 0; idx < features.length; ++idx){ 
    obj = features[idx]; 
    name = obj.properties.name; 
    if(maxName == null || name.length > maxName.length || 
     (name.length == maxName.length && name > maxName) 
    ){ 
     maxName = name; 
    } 
} 

Я все еще работаю над получением следующего имени, хотя.

0

Я думаю, что вы хотите отсортировать, что на самом деле JS имеет приятную функцию для сравнения строк. Тем не менее, он вернет это значение ("AA" > "Z") === true, чтобы вы также учитывали длину.

Я думаю, что это работает.

function sortName(a, b){ 
    a = a.properties.name; 
    b = b.properties.name; 
    if(a.length>b.length){ 
     return 1; 
    } 
    if(a > b){ 
     return 1; 
    } 
    return -1; 
} 

console.log(someObject.features.sort(sortName)[0]. properties.name); 
+0

Сортировка - это неэффективный способ нахождения максимального значения в массиве. Учитывая, что вам все равно нужно написать функцию сравнения, вы можете просто запустить одиночный цикл через массив и отслеживать максимальное значение и его индекс по мере продвижения. Конечно, для небольшого массива разница может быть незначительной, но для большего массива одиночный цикл будет намного быстрее, чем сортировка. –

0

Вы можете сделать это с помощью

var obj = { 
     "features": [{ 
      "properties": { 
       "name": "A", 
       "description": null, 
      }, 
      "type": "Feature" 
     }, { 
      "properties": { 
       "name": "B", 
       "description": null, 
      }, 
      "type": "Feature" 
     }, { 
      "properties": { 
       "name": "C", 
       "description": null, 
      }, 
      "type": "Feature" 
     }], 
     "type": "FeatureCollection" 
    }; 


    var largest = Math.max.apply(Math, findProp(obj.features, "name")); 
    console.log(changeToStr(largest + 1)); 

Где findProp получает массив значение свойства, changeToStr является преобразование числа в строку и changeToNum является преобразование числа в строку.

function changeToNum(val) { 
     var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
      i, j, result = 0; 

     for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) { 
      result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1); 
     } 
     return result; 
    }; 


    function changeToStr(number) { 
     var baseChar = ("A").charCodeAt(0), 
      letters = ""; 

     do { 
      number -= 1; 
      letters = String.fromCharCode(baseChar + (number % 26)) + letters; 
      number = (number/26) >> 0; 
     } while (number > 0); 

     return letters; 
    } 

    function findProp(obj, key, out) { 
     var i, 
      proto = Object.prototype, 
      ts = proto.toString, 
      hasOwn = proto.hasOwnProperty.bind(obj); 

     if ('[object Array]' !== ts.call(out)) out = []; 

     for (i in obj) { 
      if (hasOwn(i)) { 
       if (i === key) { 
        out.push(changeToNum(obj[i])); 
       } else if ('[object Array]' === ts.call(obj[i]) || '[object Object]' === ts.call(obj[i])) { 
        findProp(obj[i], key, out); 
       } 
      } 
     } 

     return out; 
    } 

См. Рабочий Fiddle здесь.

Смежные вопросы