2016-09-30 11 views
2

私は別の配列に基づいて並べ替える配列を持っています。両方の配列が同じ長さの場合、以下のコードは正常に動作します。しかし、私の配列orderが要素を欠いている場合、私はまだそれを新しいソートされた配列の最後に表示したいと思います。あなたが見ることができるように最後に並べ替えられた要素を保持しないで、javascriptの別の配列に基づいて配列を並べ替え

//Source arrays 
 
var order = [{_id: '123', type: '2'},{_id: '123', type: '1'}]; 
 
var elements = [{_id: '124', type: '1', name: '(should be last, not sorted)'},{_id: '123', type: '1', name: 'second(should be second)'},{_id: '123', type: '2', name: 'third(should be first)'}]; 
 

 
var sorted = []; 
 
for (var i = 0, len = order.length; i < len; i++) { 
 
    var element = elements.filter(function (el) { 
 
\t \t return el.type == order[i]['type'] && 
 
       el._id == order[i]['_id']; 
 
    }); 
 
    sorted.push(element[0]); 
 
} 
 

 
//Just for testing 
 
var list = document.createElement('ul'); 
 
for (var i = 0, len = sorted.length; i < len; i++) { 
 
     var item = document.createElement('li'); 
 
     item.appendChild(document.createTextNode(sorted[i]['name'])); 
 
     list.appendChild(item); 
 
} 
 
document.getElementById('list').appendChild(list);
<div id="list"></div>

が、今私は私のソートされた配列内の2つの項目があります。ここでは簡単な例です。最後にelementsの不足している商品を追加するにはどうすればよいですか?

答えて

1

あなたは、インデックスを取得するためにarray.findIndexを使用することができ、その後の並べ替えに応じて

var order = [{_id: '123', type: '2'},{_id: '123', type: '1'}]; 
 
var elements = [{_id: '124', type: '1', name: '(should be last, not sorted)'},{_id: '123', type: '1', name: 'second(should be second)'},{_id: '123', type: '2', name: 'third(should be first)'}]; 
 

 

 
elements.sort(function(a, b) { 
 
    var MAX_VALUE = 9999999; 
 
    var index_a = order.findIndex(function(el) { 
 
    return el._id === a._id && el.type === a.type; 
 
    }); 
 
    var index_b = order.findIndex(function(el) { 
 
    return el._id === b._id && el.type === b.type; 
 
    }); 
 
    
 
    index_a = index_a < 0? MAX_VALUE : index_a; 
 
    index_b = index_b < 0? MAX_VALUE : index_b; 
 

 
    return index_a > index_b ? 1 : index_a < index_b ? -1 : 0 
 
}); 
 

 
console.log(elements)

1

あなたはArray#sortとソート順のためのオブジェクトを使用することができます。順序が指定されていない場合、要素は最後まで移動します。

function sortWithOrder(array) { 
 
    function getOrder(o) { return (orderObj[o._id] || {})[o.type] || Infinity; } 
 

 
    var orderObj = Object.create(null); 
 
    array.forEach(function (a, i) { 
 
     orderObj[a._id] = orderObj[a._id] || {}; 
 
     orderObj[a._id][a.type] = i + 1; 
 
    }); 
 
    return function (a, b) { 
 
     return getOrder(a) - getOrder(b); 
 
    }; 
 
} 
 

 
var order = [{ _id: '123', type: '2' }, { _id: '123', type: '1' }], 
 
    elements = [{ _id: '124', type: '1', name: '(should be last, not sorted)' }, { _id: '123', type: '1', name: 'second(should be second)' }, { _id: '123', type: '2', name: 'third(should be first)' }]; 
 

 
elements.sort(sortWithOrder(order)); 
 
console.log(elements);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

'' Sort'内部getOrder'ローカル関数を定義するために、任意の特定の理由は? – Rajesh

+0

@Rajesh、ローカルでのみ使用されているためです。 –

+0

しかし、反復ごとに同じ関数を定義/オーバーライドしない*。これにはパフォーマンス上のメリットもありますか?非常に多くのクエリを申し訳ありません。 – Rajesh

1
var sorted = elements.sort((a, b) => 
       (order.findIndex(i => a._id === i._id && a.type === i.type) + 1 || order.length + 1) 
      - (order.findIndex(i => b._id === i._id && b.type === i.type) + 1 || order.length + 1) 
      ); 

'use strict'; 
 

 
var order = [{ 
 
    _id: '123', 
 
    type: '2' 
 
}, { 
 
    _id: '123', 
 
    type: '1' 
 
}]; 
 
var elements = [{ 
 
    _id: '124', 
 
    type: '1', 
 
    name: '(should be last, not sorted)' 
 
}, { 
 
    _id: '123', 
 
    type: '2', 
 
    name: 'third(should be first)' 
 
}, { 
 
    _id: '124', 
 
    type: '1', 
 
    name: '(should be last, not sorted)' 
 
}, { 
 
    _id: '123', 
 
    type: '1', 
 
    name: 'second(should be second)' 
 
}, { 
 
    _id: '123', 
 
    type: '1', 
 
    name: 'second(should be second)' 
 
}, { 
 
    _id: '123', 
 
    type: '2', 
 
    name: 'third(should be first)' 
 
}, { 
 
    _id: '123', 
 
    type: '2', 
 
    name: 'third(should be first)' 
 
}, { 
 
    _id: '123', 
 
    type: '1', 
 
    name: 'second(should be second)' 
 
}, { 
 
    _id: '124', 
 
    type: '1', 
 
    name: '(should be last, not sorted)' 
 
}]; 
 

 
var sorted = elements.sort(function (a, b) { 
 
    return (order.findIndex(function (i) { 
 
    return a._id === i._id && a.type === i.type; 
 
    }) + 1 || order.length + 1) - (order.findIndex(function (i) { 
 
    return b._id === i._id && b.type === i.type; 
 
    }) + 1 || order.length + 1); 
 
}); 
 

 
//Just for testing 
 
var list = document.createElement('ul'); 
 
for (var i = 0, len = sorted.length; i < len; i++) { 
 
     var item = document.createElement('li'); 
 
     item.appendChild(document.createTextNode(sorted[i]['name'])); 
 
     list.appendChild(item); 
 
} 
 
document.getElementById('list').appendChild(list);
<div id="list"></div>

関連する問題