如何保持"连接"订单更改时,按属性划分的对象之间是什么?

时间:2017-02-08 19:21:37

标签: javascript jquery object

我有以下数据结构:

var list = [
   {id: 156, next_item_position: 2, name: 'Item #1'}, 
   {id: 157, next_item_position: 3, name: 'Item #2'}, 
   {id: 158, next_item_position: 4, name: 'Item #3'}, 
   {id: 159, next_item_position: 5, name: 'Item #4'}, 
   {id: 160, next_item_position: 6, name: 'Item #5'}, 
   {id: 161, next_item_position: 7, name: 'Item #6'}, 
   {id: 162, next_item_position: null, name: 'Item #7'}
];

有一个名为next_item_position的属性,基本上它应该存储" next"的位置。 item(可由用户选择)。

现在,我想保持"连接"当订单发生变化时,我们有一个用于更改头寸的UI。

所以,例如:

  1. ID为(156)的项目next_item_position等于2(第2项)。
  2. 第二项的顺序从2变为3(第2至第3)。
  3. 现在我希望ID(156)的项目指向第3个位置而不是第2个位置。
  4. 我的实现如下:

      // The magic should happens here
      for(j = 0, jj = list.length; j < jj; j++) {
        var next_position = list[j].next_item_position;
    
        // Find ID of item based on its position
        var item_id = defaultPositions[next_position];
    
        // Now, find current position of "item_id"
        var current_position = currentPositions.indexOf(item_id);
    
        // And update the property
        list[j].next_item_position = current_position;
      }
    
      // Update "defaults" array
      defaultPositions = currentPositions;
    

    但不幸的是,它没有按预期工作。

    小提琴:https://jsfiddle.net/fhuk31q2/6/

2 个答案:

答案 0 :(得分:0)

这样的东西?

function moveItem ( list, id, to_pos ) {
    let list_copy = list.concat ( [] );
    let itemIndex = list_copy.findIndex ( x => { return x.id === id } );
    let item = list_copy.splice ( itemIndex, 1 ) [ 0 ];
    list_copy.splice ( to_pos, 0, item );
    list_copy = list_copy.map ( ( x, i ) => { x.next_item_position = i + 2; return x; } );
    return list_copy;
}

console.log ( moveItem ( list, 156, 3 ) );

这将获取id为156的项目(因此索引0),将其移动到您指定的任何索引,并重新排序所有&#34; next&#34;引用。

从你的描述中,我得到的是:

  • Next_item将始终是列表中的下一个项目。因此,每次移动一个项目时,都需要更新它们(例如,您将最后一个移动到第一个位置,这会将旧的第一个位置移动到第二个位置,依此类推)。
  • 复制列表以避免改变全局模型。如果你不需要它,你可以免除这个。

请注意,我同意不同的数据结构可能适合您(可能是链表)。但是,如果在您的上下文中这不可行或不实用(比如查找的速度很重要,那么数组可能是更好的选择),那么只需移动数组中的项目并根据新的重新映射refer_to_nexts数组索引(我使用+2,因为它似乎你想要一个基于&#34; 1&#34;的索引,而没有任何东西引用&#34; 1&#34; as&#34; next&#34;)。

答案 1 :(得分:0)

扩展我的评论。这可能有助于您入门。

&#13;
&#13;
var Node = function(id, name, previous) {

  this.previous = previous;
  if (previous) {
    previous.next = this;
  }
  this.id = id;
  this.name = name;

};

var swap = function(n1, n2) {

  var n1previous = n1.previous;
  var n1next = n1.next;

  n1.next = n2.next;
  if (n1.next) {
    n1.next.previous = n1;
  }
  n1.previous = n2.previous;
  if (n1.previous) {
    n1.previous.next = n1;
  }

  n2.next = n1next;
  if (n2.next) {
    n2.next.previous = n2;
  }
  n2.previous = n1previous;
  if (n2.previous) {
    n2.previous.next = n2;
  }

}
var walk = function(node) {
  if (node) {
    console.log(node.id);
    walk(node.next);
  }
}

var n1 = new Node(156, 'Item #1');
var n2 = new Node(157, 'Item #2', n1);
var n3 = new Node(158, 'Item #3', n2);
var n4 = new Node(159, 'Item #4', n3);
var n5 = new Node(160, 'Item #5', n4);
var n6 = new Node(161, 'Item #6', n5);
var n7 = new Node(162, 'Item #7', n6);

console.log('Walk');
walk(n1);

swap(n3, n7);

console.log('Walk after swap');
walk(n1);
&#13;
&#13;
&#13;

您也可以使用此库而不是编写自己的代码:http://mauriciosantos.github.io/Buckets-JS/symbols/buckets.LinkedList.html