简体   繁体   中英

sort a delimited string by json field

I have an example at http://verlager.com/demo.php

The data is read and displayed by this javascript:

let dataString = "Worl, Seymour|Jones, Jim|Smith, Paul|Jolly, Roger|";
let splitString = dataString.split("|");

for (let i = 0; i < splitString.length;) {
    $("#I" + i).val(splitString[i-1]);  i++;
}

and the supporting json:

var standing = [
    {"code" : "A", "rank" :  "1"},
    {"code" : "B", "rank" :  "2"},
    {"code" : "C", "rank" :  "3"},
    {"code" : "D", "rank" :  "4"}
];

var members = [
    {"Class": "A", "Name": "Jolly, Roger"},
    {"Class": "B", "Name": "Smith, Paul"},
    {"Class": "C","Name": "Jones, Jim"},
    {"Class": "D","Name": "Worl, Seymour"}
];

I want: "Worl, Seymour|Jones, Jim|Smith, Paul|Jolly, Roger|";

to become "Jolly, Roger|Smith, Paul|Jones, Jim|Worl, Seymour|";

Based on your comment on how you want the code to operate, I think this will do the job for you. I'm assuming that code in the standing array is the same as class in the members array. Names which are not found in the members list will be ranked at the bottom.

let dataString = "Worl, Seymour|Jones, Jim|Smith, Paul|Jolly, Roger|";
let splitString = dataString.split("|");

var standing = [
{"code" : "A", "rank" :  "1"},
{"code" : "B", "rank" :  "2"},
{"code" : "C", "rank" :  "3"},
{"code" : "D", "rank" :  "4"}
];

var members = [
{"Class": "A", "Name": "Jolly, Roger"},
{"Class": "B", "Name": "Smith, Paul"},
{"Class": "C","Name": "Jones, Jim"},
{"Class": "D","Name": "Worl, Seymour"}
];

function getRank(name) {
  var i;
  for (i = 0; i < members.length; i++)
    if (members[i].Name == name) break;
  if (i == members.length) return 9999;
  let code = members[i].Class;
  for (i = 0; i < standing.length; i++)
    if (standing[i].code == code) break;
  if (i == standing.length) return 9999;
  return parseInt(standing[i].rank);
}

function rank(name1, name2) {
  return getRank(name1) - getRank(name2);
}

console.log(splitString.sort(rank).join('|'));
Jolly, Roger|Smith, Paul|Jones, Jim|Worl, Seymour|

The following code meets your ordering criteria. I didn't put the string back together; there's not enough detail in your question to address potential corner cases. But I am assuming that what you really need is just the ordering, and you can take care of reassembling the string yourself.

let dataString = "Worl, Seymour|Jones, Jim|Smith, Paul|Jolly, Roger|";

var standing = [
    {"code" : "A", "rank" :  "1"},
    {"code" : "B", "rank" :  "2"},
    {"code" : "C", "rank" :  "3"},
    {"code" : "D", "rank" :  "4"}
];

var members = [
    {"Class": "A", "Name": "Jolly, Roger"},
    {"Class": "B", "Name": "Smith, Paul"},
    {"Class": "C","Name": "Jones, Jim"},
    {"Class": "D","Name": "Worl, Seymour"}
];

function getOrderFromClass(lhsClass, rhsClass) {
    return getOrderFromCode(lhsClass, rhsClass);
}

function getOrderFromCode(lhsCode, rhsCode) {
  var lhsRank, rhsRank;

  for(let s of standing) {
      if(s["code"] === lhsCode) { lhsRank = s["rank"]; }
      if(s["code"] === rhsCode) { rhsRank = s["rank"]; }
  }

  if(lhsRank < rhsRank) { return -1; }
  else if(lhsRank > rhsRank) { return 1; }
  else { return 0; }
}

let splitString = dataString.split("|");
console.log(splitString);

splitString.sort(function(lhsName, rhsName) {
    var lhsClass, rhsClass;

    for(let m of members) {
        if(m["Name"] === lhsName) { lhsClass = m["Class"]; }
        if(m["Name"] === rhsName) { rhsClass = m["Class"]; }
    }

    return getOrderFromClass(lhsClass, rhsClass);
});

// All done
console.log(splitString);

I will assume that all names are valid, ie exist in the members array, to keep the code simple.

 var standing = [ { "code": "A", "rank": "1" }, { "code": "B", "rank": "2" }, { "code": "C", "rank": "3" }, { "code": "D", "rank": "4" } ]; var members = [ { "Class": "A", "Name": "Jolly, Roger" }, { "Class": "B", "Name": "Smith, Paul" }, { "Class": "C", "Name": "Jones, Jim" }, { "Class": "D", "Name": "Worl, Seymour" } ]; const dataString = "Worl, Seymour|Jones, Jim|Smith, Paul|Jolly, Roger|"; // Filter out the empty string that split() produces at the end const names = dataString.split("|").filter(name => name.length > 0); // Map the names to members const ms = names.map(name => members.find(m => m.Name === name)); // Map the members to standings const ss = ms.map(m => standing.find(s => s.code === m.Class)); // Now fill the result with the names in the order of their ranking const result = []; names.forEach((name, i) => result[ss[i].rank - 1] = name); for (let i = 0; i < result.length; i++) { $("#I" + (i+1)).val(result[i]); } 

You seem to have some kind of indexing problem in the last part where you update the DOM elements, so I took my best guess at what you are trying to do there. But since you haven't posted your HTML, I don't know if this is exactly right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM