Reputation: 1395
Say I have an array, [1, 2, 3, 4, 5, 3, 4, 6, 3, 7, 4]
. I want to swap the values of 3 and 4 iff they are adjacent an in the order [3, 4]
(i.e. [4, 3]
remain intact). The result of the example would be [1, 2, 4, 3, 5, 4, 3, 6, 3, 7, 4]
.
Is there an elegant way to do this in Lodash without the use of for
loops?
Edit: How about
_.sortBy(arr, function(value, index) {
if (value === 3) {
return index + 0.75;
} else if (value === 4) {
return index - 0.75;
} else {
return index
}
});
Edit 2: Went with the following (it's not actually 3 and 4).
return _.reduce(tags, function(out, tag) {
var word = tag[0];
if (out[0] && unitPowerSuffixes.hasOwnProperty(word)) {
out.splice(-1, 0, {
type: 'unit-power',
value: unitPowerSuffixes[word]
}); // Insert one from end
} else {
out.push(tag);
}
return out;
}, []);
Upvotes: 1
Views: 3048
Reputation: 664599
A really functional way would be to use something like splitOn
. But we can do that using strings (not even needing lodash):
arr.join().split("3,4").join("4,3").split(",").map(Number)
Upvotes: 1
Reputation: 74204
Is there an elegant way to do this in Lodash without the use of
for
loops?
Yes, you can use reduce
as follows:
var array = [1, 2, 3, 4, 5, 3, 4, 6, 3, 7, 4];
var result = _.reduce(array, swapAdjacentInOrder(3, 4), []);
alert(JSON.stringify(result));
function swapAdjacentInOrder(a, b) {
return function (result, element) {
var length = result.length;
if (length > 0 && element === b) {
var last = length - 1;
if (result[last] === a) {
result[last] = b;
element = a;
}
}
result[length] = element;
return result;
};
}
<script src="https://rawgit.com/lodash/lodash/master/lodash.min.js"></script>
However, the swapAdjacentInOrder
function also has the following property:
var array = [3, 4, 4, 4];
var result = _.reduce(array, swapAdjacentInOrder(3, 4), []);
alert(JSON.stringify(result)); // [4, 4, 4, 3]
function swapAdjacentInOrder(a, b) {
return function (result, element) {
var length = result.length;
if (length > 0 && element === b) {
var last = length - 1;
if (result[last] === a) {
result[last] = b;
element = a;
}
}
result[length] = element;
return result;
};
}
<script src="https://rawgit.com/lodash/lodash/master/lodash.min.js"></script>
If you don't want that then you can do the following updated swapAdjacentInOrder
function:
var array = [3, 4, 4, 4];
var result = _.reduce(array, swapAdjacentInOrder(3, 4), []);
alert(JSON.stringify(result)); // [4, 3, 4, 4]
function swapAdjacentInOrder(a, b) {
return function (result, element) {
var length = result.length;
if (length > 0 && element === b) {
var last = length - 1;
if (result[last] !== a || last > 0 && result[last - 1] === b);
else {
result[last] = b;
element = a;
}
}
result[length] = element;
return result;
};
}
<script src="https://rawgit.com/lodash/lodash/master/lodash.min.js"></script>
Hope that helps.
Upvotes: 1